"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.

参考:

  Module "pdb"
     Interactive source code debugger for Python programs.

  Module "traceback"
     Standard interface to extract, format and print stack traces of
     Python programs.


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.disable()

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

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
