スタックトレース

コンピュータにおいて、スタックトレース英語: stack trace)とは、プログラムの実行中の特定の時点でのアクティブなスタックフレームのレポートである。スタックバックトレース英語: stack backtrace[1])、スタックトレースバック英語: stack traceback[2])とも言い、単にバックトレースとも言う(gdbでのレポートコマンドは、バックトレース(backtrace)を縮めたbtである)。

プログラムが実行されると、多くの場合、スタックヒープの2つの場所にメモリが動的に割り当てられる。スタックという言葉はプログラムの構文についても使われるため、区別するために、このスタックはコールスタック(call stack)と呼ばれる。技術的には、メモリブロックがスタックに割り当てられると、その前に他のメモリブロックが割り当てられている可能性があるため、簡単に削除することはできない。プログラムで関数が呼び出されるたびに、スタックフレーム(またはアクティベーションレコード)と呼ばれるコールスタックの最上部にメモリブロックが割り当てられる。高レベルでは、スタックフレームは、関数内で宣言された関数のパラメータとローカル変数にメモリを割り当てる。

プログラマは通常、デバッグにおいてスタックトレースを使用する。エンドユーザには、エラーメッセージの一部としてスタックトレースが表示されることがあり、障害報告の際に使用する。

スタックトレースを使用すると、スタックトレースが生成されるまでの、呼び出された入れ子関数英語版のシーケンスを追跡できる。事後分析では、障害が発生した関数まで追跡できる(ただし必ずしも追跡できるわけではない)。末尾再帰はスタックトレースに表示されない。

次の、エラーが含まれた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から、関数bは関数aから、関数aはプログラムの15行目(最終行)から呼び出されたことも示している。

これらの3つの関数のそれぞれのアクティベーションレコードは、関数aがスタックの下部を占有し、関数cがスタックの上部を占有するようにスタックに配置される。

プログラミング言語によるサポート編集

JavaC#など多くのプログラミング言語には、システムコールを介して現在のスタックトレースを取得するための機能が組み込まれている。C++にはこれを行うための組み込みの機能はないが、stacktraceライブラリなどを使用してスタックトレースを取得できる。JavaScriptでは、例外が、スローされた場所からのスタックを含むstackプロパティを保持している。

関連項目編集

脚注編集

  1. ^ libc manual: backtraces”. gnu.org. 2014年7月8日閲覧。
  2. ^ traceback — Print or retrieve a stack traceback”. python.org. 2014年7月8日閲覧。