faulthandler --- Python tracebackのダンプ¶
バージョン 3.3 で追加.
このモジュールは、例外発生時、タイムアウト時、ユーザシグナルの発生時などのタイミングでpython tracebackを明示的にダンプするための関数を含んでいます。これらのシグナル、SIGSEGV、SIGFPE、SIGABRT、SIGBUS、SIGILL に対するフォールトハンドラをインストールするには 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がデッドロックした場合でもダンプができます。
The Python Development Mode calls faulthandler.enable()
at Python startup.
参考
tracebackのダンプ¶
-
faulthandler.dump_traceback(file=sys.stderr, all_threads=True)¶ 全スレッドのtracebackを file へダンプします。もし all_threads が
Falseであれば、現在のスレッドのみダンプします。参考
traceback.print_tb(), which can be used to print a traceback object.バージョン 3.5 で変更: Added support for passing file descriptor to this function.
フォールトハンドラの状態¶
-
faulthandler.enable(file=sys.stderr, all_threads=True)¶ フォールトハンドラを有効にします。
SIGSEGV、SIGFPE、SIGABRT、SIGBUS、SIGILLシグナルに対して Pythonのtracebackをダンプするハンドラをインストールします。もし all_threads がTrueであれば、すべての実行中のスレッドについてtracebackをダンプします。そうでなければ現在のスレッドのみダンプします。The file must be kept open until the fault handler is disabled: see issue with file descriptors.
バージョン 3.5 で変更: Added support for passing file descriptor to this function.
バージョン 3.6 で変更: On Windows, a handler for Windows exception is also installed.
バージョン 3.10 で変更: The dump now mentions if a garbage collector collection is running if all_threads is true.
-
faulthandler.is_enabled()¶ フォールトハンドラが有効かどうかチェックします。
タイムアウト後にtracebackをダンプする¶
-
faulthandler.dump_traceback_later(timeout, repeat=False, file=sys.stderr, exit=False)¶ timeout 秒経過後か、repeat が
Trueの場合は timeout 秒おきに全スレッドの traceback をダンプします。もし exit がTrueであればtracebackをダンプした後、status=1で_exit()を呼び出します。(注:_exit()を呼び出すとプロセスを即座に終了します。つまりファイルバッファのクリアといった終了処理を行いません。)関数が2回呼ばれた場合、最新の呼び出しが前回の呼び出しパラメータを引き継いでタイムアウト時間をリセットします。タイマーの分解能は1秒未満です。The file must be kept open until the traceback is dumped or
cancel_dump_traceback_later()is called: see issue with file descriptors.This function is implemented using a watchdog thread.
バージョン 3.7 で変更: This function is now always available.
バージョン 3.5 で変更: Added support for passing file descriptor to this function.
-
faulthandler.cancel_dump_traceback_later()¶ dump_traceback_later()の最新の呼び出しをキャンセルします。
ユーザシグナルに対してtracebackをダンプする¶
-
faulthandler.register(signum, file=sys.stderr, all_threads=True, chain=False)¶ ユーザシグナルを登録します: すべてのスレッドでtracebackをダンプするために signum シグナルをインストールします。ただし all_threads が
Falseであれば現在のスレッドのみ file にダンプします。もし chain がTrueであれば以前のハンドラも呼び出します。The file must be kept open until the signal is unregistered by
unregister(): see issue with file descriptors.Windowsでは利用不可です。
バージョン 3.5 で変更: Added support for passing file descriptor to this function.
-
faulthandler.unregister(signum)¶ ユーザシグナルを登録解除します:
register()でインストールした signum シグナルハンドラをアンインストールします。シグナルが登録された場合はTrueを返し、そうでなければFalseを返します。Windowsでは利用不可です。
ファイル記述子の問題¶
enable()、dump_traceback_later() ならびに register() は引数 file に渡されたファイル記述子を保持します。ファイルが閉じられファイル記述子が新しいファイルで再利用された場合や、os.dup2() の使用でファイル記述子が置き換えた場合、 traceback の結果は別のファイルへ書き込まれます。ファイルが置き換えられた場合は、毎回これらの関数を呼び出しなおしてください。
使用例¶
フォールトハンドラを有効化・無効化したときの Linuxでのセグメンテーションフォールトの例:
$ python3 -c "import ctypes; ctypes.string_at(0)"
Segmentation fault
$ python3 -q -X faulthandler
>>> import ctypes
>>> ctypes.string_at(0)
Fatal Python error: Segmentation fault
Current thread 0x00007fb899f39700 (most recent call first):
File "/home/python/cpython/Lib/ctypes/__init__.py", line 486 in string_at
File "<stdin>", line 1 in <module>
Segmentation fault