Трассировка стека

Материал из Википедии — свободной энциклопедии
Перейти к навигации Перейти к поиску

Трассировка стека (от англ. 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 которое содержит трассировку стека в том месте, где они произошли.