"faulthandler" --- Python トレースバックをダンプする
****************************************************

Added in version 3.3.

======================================================================

このモジュールには、Python のトレースバックを明示的にダンプしたり、フ
ォールトの発生時、タイムアウト後、ユーザーシグナルの受信時にダンプした
りする関数があります。 "SIGSEGV"、"SIGFPE"、"SIGABRT"、"SIGBUS"、
"SIGILL" シグナルに対するフォールトハンドラを登録するには、
"faulthandler.enable()" を呼び出してください。 環境変数
"PYTHONFAULTHANDLER" を設定するか、コマンドラインオプション "-X"
"faulthandler" を指定すると、起動時に有効にすることもできます。

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

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

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

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

* ファイル名、関数名、行番号だけを表示します (ソースコードは表示しませ
  ん)。

* 1 スレッドあたり 100 フレーム、合計 100 スレッドに制限されています (
  スレッド数は *max_threads* で設定できます)。

* 順序は逆で、最も新しい呼び出しから表示します。

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

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

Python 開発モード は Python の起動時に "faulthandler.enable()" を呼び
出します。

参考:

  "pdb" モジュール
     Python プログラム用の対話的なソースコードデバッガです。

  "traceback" モジュール
     Python プログラムのスタックトレースを抽出、書式化、表示する標準イ
     ンターフェイスです。


tracebackのダンプ
=================

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

   すべてのスレッドのトレースバックを *file* にダンプします。
   *all_threads* が "False" の場合は現在のスレッドだけをダンプします。
   *max_threads* はダンプするスレッド数の上限です。

   参考: トレースバックオブジェクトの表示に使える "traceback.print_tb()"。

   バージョン 3.5 で変更: この関数にファイル記述子を渡せるようになりま
   した。

   バージョン 3.15 で変更: キーワード引数 *max_threads* が追加されまし
   た。


C スタックのダンプ
==================

Added in version 3.14.

faulthandler.dump_c_stack(file=sys.stderr)

   現在のスレッドの C スタックトレースを *file* にダンプします。

   Python のビルドが対応していない場合や、OS がスタックトレースを提供
   しない場合は、C スタックのダンプの代わりにエラーを表示します。


C スタックの互換性
------------------

システムが C レベルの *backtrace(3)* または *dladdr1(3)* をサポートし
ない場合、C スタックのダンプは機能しません。 スタックの代わりにエラー
を表示します。

また、一部のコンパイラは *CPython* の C スタックのダンプ実装をサポート
しません。 そのため OS がスタックのダンプをサポートしていても、スタッ
クの代わりに別のエラーが表示される場合があります。

注釈:

  C スタックのダンプは、呼び出しスタック内のバイナリの DWARF レベルに
  よっては非常に時間がかかる場合があります。


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

faulthandler.enable(file=sys.stderr, all_threads=True, c_stack=True, *, max_threads=100)

   フォールトハンドラを有効にします。 Python のトレースバックをダンプ
   するために、"SIGSEGV"、"SIGFPE"、"SIGABRT"、"SIGBUS"、"SIGILL" シグ
   ナルのハンドラを登録します。 *all_threads* が "True" の場合は、実行
   中のすべてのスレッドのトレースバックを出力します。 それ以外の場合は
   現在のスレッドだけをダンプします。

   フォールトハンドラを無効にするまで *file* を開いたままにしておく必
   要があります。 ファイル記述子の問題 を参照してください。

   *c_stack* が "True" の場合、システムがサポートしていれば Python の
   トレースバックの後に C スタックトレースを表示します。 互換性の詳細
   は "dump_c_stack()" を参照してください。

   *max_threads* は、致命的なシグナルの発生時にダンプするスレッド数の
   上限です。

   バージョン 3.5 で変更: この関数にファイル記述子を渡せるようになりま
   した。

   バージョン 3.6 で変更: Windows では、Windows 例外のハンドラも登録す
   るようになりました。

   バージョン 3.10 で変更: *all_threads* が真で、ガベージコレクタが回
   収処理を実行中の場合、そのこともダンプに表示するようになりました。

   バージョン 3.14 で変更: データ競合の危険を防ぐため、*GIL* が無効の
   場合は現在のスレッドだけをダンプするようになりました。

   バージョン 3.14 で変更: *c_stack* が真の場合、ダンプに C スタックト
   レースも表示するようになりました。

   バージョン 3.15 で変更: キーワード引数 *max_threads* が追加されまし
   た。

faulthandler.disable()

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

faulthandler.is_enabled()

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


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

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

   *timeout* 秒後に、または *repeat* が "True" の場合は *timeout* 秒ご
   とに、すべてのスレッドのトレースバックをダンプします。 *exit* が
   "True" の場合、トレースバックをダンプした後に終了ステータス 1 で
   "_exit()" を呼び出します。 ("_exit()" はプロセスを直ちに終了するた
   め、ファイルバッファのフラッシュなどの後処理は行いません。) この関
   数を 2 回呼び出すと、新しい呼び出しで以前のパラメータを置き換え、タ
   イムアウトをリセットします。 タイマーの分解能は 1 秒未満です。
   *max_threads* はダンプするスレッド数の上限です。

   トレースバックがダンプされるか "cancel_dump_traceback_later()" が呼
   び出されるまで、*file* を開いたままにしておく必要があります。 ファ
   イル記述子の問題 を参照してください。

   この関数は監視用のスレッドを使って実装されています。

   バージョン 3.5 で変更: この関数にファイル記述子を渡せるようになりま
   した。

   バージョン 3.7 で変更: この関数は常に利用可能になりました。

   バージョン 3.15 で変更: キーワード引数 *max_threads* が追加されまし
   た。

faulthandler.cancel_dump_traceback_later()

   "dump_traceback_later()" の最新の呼び出しをキャンセルします。


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

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

   ユーザーシグナルを登録します。 *signum* シグナルのハンドラを登録し
   、すべてのスレッド、または *all_threads* が "False" の場合は現在の
   スレッドのトレースバックを *file* にダンプします。 "chain" が
   "True" の場合は以前のハンドラも呼び出します。 *max_threads* はダン
   プするスレッド数の上限です。

   "unregister()" でシグナルの登録を解除するまで、*file* を開いたまま
   にしておく必要があります。 ファイル記述子の問題 を参照してください
   。

   Windowsでは利用不可です。

   バージョン 3.5 で変更: この関数にファイル記述子を渡せるようになりま
   した。

   バージョン 3.15 で変更: キーワード引数 *max_threads* が追加されまし
   た。

faulthandler.unregister(signum)

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

   Windowsでは利用不可です。


ファイル記述子の問題
====================

"enable()"、"dump_traceback_later()" ならびに "register()" は引数
*file* に渡されたファイル記述子を保持します。ファイルが閉じられファイ
ル記述子が新しいファイルで再利用された場合や、"os.dup2()" の使用でファ
イル記述子が置き換えた場合、 traceback の結果は別のファイルへ書き込ま
れます。ファイルが置き換えられた場合は、毎回これらの関数を呼び出しなお
してください。


使用例
======

フォールトハンドラを有効化・無効化したときの Linuxでのセグメンテーショ
ンフォールトの例:

   $ python -c "import ctypes; ctypes.string_at(0)"
   Segmentation fault

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

   Current thread 0x00007fb899f39700 (most recent call first):
     File "/opt/python/Lib/ctypes/__init__.py", line 486 in string_at
     File "<stdin>", line 1 in <module>

   Current thread's C stack trace (most recent call first):
     Binary file "/opt/python/python", at _Py_DumpStack+0x42 [0x5b27f7d7147e]
     Binary file "/opt/python/python", at +0x32dcbd [0x5b27f7d85cbd]
     Binary file "/opt/python/python", at +0x32df8a [0x5b27f7d85f8a]
     Binary file "/usr/lib/libc.so.6", at +0x3def0 [0x77b73226bef0]
     Binary file "/usr/lib/libc.so.6", at +0x17ef9c [0x77b7323acf9c]
     Binary file "/opt/python/build/lib.linux-x86_64-3.15/_ctypes.cpython-315d-x86_64-linux-gnu.so", at +0xcdf6 [0x77b7315dddf6]
     Binary file "/usr/lib/libffi.so.8", at +0x7976 [0x77b73158f976]
     Binary file "/usr/lib/libffi.so.8", at +0x413c [0x77b73158c13c]
     Binary file "/usr/lib/libffi.so.8", at ffi_call+0x12e [0x77b73158ef0e]
     Binary file "/opt/python/build/lib.linux-x86_64-3.15/_ctypes.cpython-315d-x86_64-linux-gnu.so", at +0x15a33 [0x77b7315e6a33]
     Binary file "/opt/python/build/lib.linux-x86_64-3.15/_ctypes.cpython-315d-x86_64-linux-gnu.so", at +0x164fa [0x77b7315e74fa]
     Binary file "/opt/python/build/lib.linux-x86_64-3.15/_ctypes.cpython-315d-x86_64-linux-gnu.so", at +0xc624 [0x77b7315dd624]
     Binary file "/opt/python/python", at _PyObject_MakeTpCall+0xce [0x5b27f7b73883]
     Binary file "/opt/python/python", at +0x11bab6 [0x5b27f7b73ab6]
     Binary file "/opt/python/python", at PyObject_Vectorcall+0x23 [0x5b27f7b73b04]
     Binary file "/opt/python/python", at _PyEval_EvalFrameDefault+0x490c [0x5b27f7cbb302]
     Binary file "/opt/python/python", at +0x2818e6 [0x5b27f7cd98e6]
     Binary file "/opt/python/python", at +0x281aab [0x5b27f7cd9aab]
     Binary file "/opt/python/python", at PyEval_EvalCode+0xc5 [0x5b27f7cd9ba3]
     Binary file "/opt/python/python", at +0x255957 [0x5b27f7cad957]
     Binary file "/opt/python/python", at +0x255ab4 [0x5b27f7cadab4]
     Binary file "/opt/python/python", at _PyEval_EvalFrameDefault+0x6c3e [0x5b27f7cbd634]
     Binary file "/opt/python/python", at +0x2818e6 [0x5b27f7cd98e6]
     Binary file "/opt/python/python", at +0x281aab [0x5b27f7cd9aab]
     Binary file "/opt/python/python", at +0x11b6e1 [0x5b27f7b736e1]
     Binary file "/opt/python/python", at +0x11d348 [0x5b27f7b75348]
     Binary file "/opt/python/python", at +0x11d626 [0x5b27f7b75626]
     Binary file "/opt/python/python", at PyObject_Call+0x20 [0x5b27f7b7565e]
     Binary file "/opt/python/python", at +0x32a67a [0x5b27f7d8267a]
     Binary file "/opt/python/python", at +0x32a7f8 [0x5b27f7d827f8]
     Binary file "/opt/python/python", at +0x32ac1b [0x5b27f7d82c1b]
     Binary file "/opt/python/python", at Py_RunMain+0x31 [0x5b27f7d82ebe]
     <truncated rest of calls>
   Segmentation fault
