Трассировка стека
Трассировка стека (от англ. 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++ могут извлекать трассировки стека с помощью (например) библиотеки stacktrace. В языке JavaScript исключения имеют свойство stack
которое содержит трассировку стека в том месте, где они произошли.