27.2. faulthandler — Python tracebackのダンプ

このモジュールは、例外発生時、タイムアウト時、ユーザシグナルの発生時などのタイミングでpython tracebackを明示的にダンプするための関数を含んでいます。これらのシグナル、SIGSEGVSIGFPESIGABRTSIGBUSSIGILL に対するフォールトハンドラをインストールするには faulthandler.enable() を実行してください。python起動時に有効にするには環境変数 PYTHONFAULTHANDLER を設定するか、コマンドライン引数に -X faulthandler を指定してください。

Pythonのフォールトハンドラは、apportやWindowsのフォールトハンドラのようなシステムフォールトハンドラと互換性があります。このモジュールは sigaltstack() 関数が使用可能であればシグナルハンドラ用に代替スタックを利用します。これによってスタックオーバーフロー時にもスタックトレースを出力することができます。

フォールトハンドラは絶望的なケースで呼び出されます。そのためシグナルセーフな関数しか使うことができません (例: ヒープメモリ上にメモリ確保はできません)。この制限により、tracebackのダンプ機能は通常のPythonのtracebackと比べて小さいです:

  • ASCIIのみサポートされます。エンコード時には backslashreplace エラーハンドラを使用します。

  • すべての文字列は500文字以内に制限されています。

  • ファイル名、関数名、行数のみ表示します(ソースコードの表示はありません)。

  • 100フレーム、100スレッドに制限されています。

デフォルトでは、Pythonのtracebackは sys.stderr に書き出されます。tracebackを見るには、対象アプリケーションはターミナル上で実行しなければなりません。 faulthandler.enable() に渡す引数によってログファイルを指定することができます。

モジュールはC言語で実装されているので、アプリのクラッシュ時でもPythonがデッドロックした場合でもダンプができます。

バージョン 3.3 で追加.

27.2.1. tracebackのダンプ

faulthandler.dump_traceback(file=sys.stderr, all_threads=True)

すべてのスレッドのtracebackを file へダンプします。もし all_threadsFalse であれば、現在のスレッドのみダンプします。

27.2.2. フォールトハンドラの状態

faulthandler.enable(file=sys.stderr, all_threads=True)

フォールトハンドラを有効にします。 SIGSEGVSIGFPESIGABRTSIGBUSSIGILL シグナルに対して Pythonのtracebackをダンプするハンドラをインストールします。もし all_threadsTrue であれば、すべての実行中のスレッドについてtracebackをダンプします。そうでなければ現在のスレッドのみダンプします。

faulthandler.disable()

フォールトハンドラを無効にします: enable() によってインストールされたシグナルハンドラをアンインストールします。

faulthandler.is_enabled()

フォールトハンドラが有効かどうかチェックします。

27.2.3. タイムアウト後にtracebackをダンプする

faulthandler.dump_traceback_later(timeout, repeat=False, file=sys.stderr, exit=False)

timeout 時間が経過後、もしくは repeatTrue であれば timeout 時間が経過ごとに毎回 traceback をダンプします。もし exitTrue であればtracebackをダンプ後、status=1で _exit() を呼び出します。(注: _exit() を呼び出すとプロセスを即座に終了します。つまりファイルバッファをクリアするといったような終了処理をおこないません。)もし関数が2度呼ばれると最新の呼び出しが前回の呼び出しパラメータを引き継いでタイムアウト時間をリセットします。タイマーの分解能は1秒未満です。

この関数は番犬(watchdog)スレッドを使って実装されているため、Pythonがスレッド無効でコンパイルされている場合は利用できません。

faulthandler.cancel_dump_traceback_later()

最新の呼び出しをキャンセルするには:func:`dump_traceback_later`を実行します

27.2.4. ユーザシグナルに対してtracebackをダンプするには

faulthandler.register(signum, file=sys.stderr, all_threads=True, chain=False)

ユーザシグナルを登録します: すべてのスレッドでtracebackをダンプするために signum シグナルをインストールします。ただし all_threadsFalse であれば現在のスレッドのみ file にダンプします。もし chain が True であれば以前のハンドラも呼び出します。

Windowsでは利用不可です。

faulthandler.unregister(signum)

ユーザシグナルを登録解除します: register() でインストールした signum シグナルハンドラをアンインストールします。シグナルが登録された際は True が返却され、そうでなければ False が返却されます。

Windowsでは利用不可です。

27.2.5. ファイル記述子の問題

:func:`enable`と、:func:`dump_traceback_later`と:func:`register`は引数 file に渡されたファイル記述子を保持します。もしファイルが閉じられるか新しいファイルで再利用された場合、もしくは:func:`os.dup2`が利用された場合はファイル記述子は自動で置き換わり、 traceback の結果は別のファイルへ書き込まれます。ファイルが置き換えられた際にはこれらの関数を呼び出しなおしてください。

27.2.6. 例

Linuxでのセグメンテーションフォールト時の例:

$ python -q -X faulthandler
>>> import ctypes
>>> ctypes.string_at(0)
Fatal Python error: Segmentation fault

Current thread 0x00007fb899f39700:
  File "/home/python/cpython/Lib/ctypes/__init__.py", line 486 in string_at
  File "<stdin>", line 1 in <module>
Segmentation fault