Переполнение стека
- 1 year ago
- 0
- 0
Трассировка стека (от англ. stack trace) — это отчёт о действующих кадрах стека в определённый момент времени во время выполнения программы . Когда программа запускается, память обычно динамически выделяется в двух местах: на стеке и в куче . Память постоянно выделяется на стеке, но не обязательно в куче. Каждый раз, когда функция вызывается в программе, блок памяти выделяется поверх исполняющегося кадра стека. На высоком уровне кадр выделяется, чтобы содержать параметры функции и локальные переменные, объявленные в ней.
Программисты обычно используют трассировку стека во время интерактивной, а также посмертной отладки . Конечные пользователи могут увидеть трассировку стека как часть сообщения об ошибке, о которой они могут затем сообщить программисту.
Трассировка стека позволяет отслеживать последовательность вызванных функций - до точки, в которой трассировка стека была создана. В посмертном сценарии это распространяется на функцию, в которой произошел сбой (что не обязательно там же где он был создан).
В качестве примера, следующая программа Python содержит ошибку:
def a():
i = 0
j = b(i)
return j
def b(z):
k = 5
if z == 0:
c()
return k + z
def c():
error()
a()
При запуске программы в стандартном интерпретаторе Python появляется следующее сообщение об ошибке:
Traceback (most recent call last):
File "tb.py", line 15, in <module>
a()
File "tb.py", line 3, in a
j = b(i)
File "tb.py", line 9, in b
c()
File "tb.py", line 13, in c
error()
NameError: name 'error' is not defined
Трассировка стека показывает, что ошибка возникла в функции
c
. Она также показывает, что функция
c
была вызвана функцией
b
, которая была вызвана функцией
a
, а та, в свою очередь, была вызвана кодом на 15-й строчке кода программы. Стековые кадры каждой из этих трёх функций были бы расположены в стеке таким образом, что функция
a
занимала нижнюю часть стека, а функция
c
- верхнюю.
Многие языки программирования, включая
Java
и
C#
, имеют встроенную поддержку для получения текущей трассировки стека с помощью системных вызовов.
C++
не имеет встроенной поддержки для этого, но пользователи C++ могут извлекать трассировки стека с помощью (например)
библиотеки
. В языке
JavaScript
исключения
имеют свойство
stack
которое содержит трассировку стека в том месте, где они произошли.