faulthandler
--- 轉儲 Python 回溯¶
在 3.3 版本加入。
此模組包含的函式可以在發生故障、超時或收到使用者訊號時顯式地轉儲 Python 回溯資訊。呼叫 faulthandler.enable()
可為 SIGSEGV
、SIGFPE
、SIGABRT
、SIGBUS
和 SIGILL
訊號安裝故障處理程式。你也可以透過設定 PYTHONFAULTHANDLER
環境變數或使用 -X
faulthandler
命令列選項在啟動時啟用它們。
故障處理程式與 Apport 或 Windows 故障處理程式等系統故障處理程式相容。如果 sigaltstack()
函式可用,該模組會為訊號處理程式使用備用堆疊。這使得它即使在堆疊溢位時也能轉儲回溯資訊。
故障處理程式是在發生災難性情況時呼叫的,因此只能使用訊號安全 (signal-safe) 的函式(例如,它不能在堆上分配記憶體)。由於此限制,與正常的 Python 回溯資訊相比,回溯資訊的轉儲是最小化的。
只支援 ASCII。編碼時使用
backslashreplace
錯誤處理程式。每個字串限制為 500 個字元。
只顯示檔名、函式名和行號。(沒有原始碼)
它被限制在 100 個幀和 100 個執行緒內。
順序是顛倒的:最新的呼叫會最先顯示。
預設情況下,Python 回溯資訊會寫入 sys.stderr
。要看到回溯資訊,應用程式必須在終端中執行。或者也可以將日誌檔案傳遞給 faulthandler.enable()
。
該模組是用 C 實現的,因此可以在崩潰或 Python 死鎖時轉儲回溯資訊。
Python 開發模式 會在 Python 啟動時呼叫 faulthandler.enable()
。
轉儲回溯資訊¶
- faulthandler.dump_traceback(file=sys.stderr, all_threads=True)¶
將所有執行緒的回溯資訊轉儲到 file 中。如果 all_threads 為
False
,則只轉儲當前執行緒。參見
traceback.print_tb()
可用於列印回溯物件。在 3.5 版更改: 增加了向此函式傳遞檔案描述符的支援。
轉儲 C 堆疊¶
在 3.14 版本加入。
- faulthandler.dump_c_stack(file=sys.stderr)¶
將當前執行緒的 C 堆疊跟蹤轉儲到 file 中。
如果 Python 構建不支援或作業系統不提供堆疊跟蹤,那麼這會列印一個錯誤資訊,而不是轉儲 C 堆疊。
C 堆疊相容性¶
如果系統不支援 C 級別的 backtrace(3) 或 dladdr1(3),那麼 C 堆疊轉儲將無法工作。將會列印錯誤資訊而不是堆疊。
此外,某些編譯器不支援 CPython 的 C 堆疊轉儲實現。因此,即使作業系統支援轉儲堆疊,也可能會列印一個不同的錯誤資訊而不是堆疊。
備註
轉儲 C 堆疊的速度可能會非常慢,具體取決於呼叫堆疊中二進位制檔案的 DWARF 級別。
故障處理程式狀態¶
- faulthandler.enable(file=sys.stderr, all_threads=True, c_stack=True)¶
啟用故障處理程式:為
SIGSEGV
、SIGFPE
、SIGABRT
、SIGBUS
和SIGILL
訊號安裝處理程式以轉儲 Python 回溯資訊。如果 all_threads 為True
,則為每個正在執行的執行緒生成回溯資訊。否則,只轉儲當前執行緒。file 必須保持開啟狀態,直到故障處理程式被停用:請參閱檔案描述符問題。
如果 c_stack 為
True
,那麼 C 堆疊跟蹤將在 Python 回溯之後列印,除非系統不支援。有關相容性的更多資訊,請參閱dump_c_stack()
。在 3.5 版更改: 增加了向此函式傳遞檔案描述符的支援。
在 3.6 版更改: 在 Windows 上,還會安裝一個 Windows 異常處理程式。
在 3.10 版更改: 如果 all_threads 為真,轉儲現在會提及垃圾回收器回收是否正在執行。
在 3.14 版更改: 如果停用了 GIL,為避免資料競爭的風險,只會轉儲當前執行緒。
在 3.14 版更改: 如果 c_stack 為真,轉儲現在會顯示 C 堆疊跟蹤。
- faulthandler.is_enabled()¶
檢查故障處理程式是否已啟用。
超時後轉儲回溯資訊¶
- faulthandler.dump_traceback_later(timeout, repeat=False, file=sys.stderr, exit=False)¶
在 timeout 秒的超時後,轉儲所有執行緒的回溯資訊;如果 repeat 是
True
,則每隔 timeout 秒轉儲一次。如果 exit 是True
,則在轉儲回溯資訊後以狀態碼 1 呼叫_exit()
。(注意_exit()
會立即退出程序,這意味著它不會執行任何清理工作,如重新整理檔案緩衝區。)如果該函式被呼叫兩次,新的呼叫將替換之前的引數並重置超時。計時器的解析度為亞秒級。file 必須保持開啟狀態,直到回溯資訊被轉儲或呼叫
cancel_dump_traceback_later()
:請參閱檔案描述符問題。此函式透過一個看門狗執行緒實現。
在 3.5 版更改: 增加了向此函式傳遞檔案描述符的支援。
在 3.7 版更改: 此函式現在總是可用的。
- faulthandler.cancel_dump_traceback_later()¶
取消對
dump_traceback_later()
的最後一次呼叫。
在使用者訊號上轉儲回溯資訊¶
- faulthandler.register(signum, file=sys.stderr, all_threads=True, chain=False)¶
註冊一個使用者訊號:為 signum 訊號安裝一個處理程式,將所有執行緒的回溯資訊(如果 all_threads 為
False
,則為當前執行緒)轉儲到 file 中。如果 chain 為True
,則呼叫前一個處理程式。file 必須保持開啟狀態,直到透過
unregister()
取消註冊該訊號:請參閱檔案描述符問題。在 Windows 上不可用。
在 3.5 版更改: 增加了向此函式傳遞檔案描述符的支援。
- faulthandler.unregister(signum)¶
取消註冊使用者訊號:解除安裝由
register()
安裝的 signum 訊號的處理程式。如果訊號已註冊,則返回True
,否則返回False
。在 Windows 上不可用。
檔案描述符問題¶
enable()
、dump_traceback_later()
和 register()
會保留其 file 引數的檔案描述符。如果檔案被關閉,其檔案描述符被新檔案重用,或者使用 os.dup2()
替換了檔案描述符,回溯資訊將被寫入不同的檔案。每次替換檔案時,都應重新呼叫這些函式。
示例¶
在 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.14/_ctypes.cpython-314d-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.14/_ctypes.cpython-314d-x86_64-linux-gnu.so", at +0x15a33 [0x77b7315e6a33]
Binary file "/opt/python/build/lib.linux-x86_64-3.14/_ctypes.cpython-314d-x86_64-linux-gnu.so", at +0x164fa [0x77b7315e74fa]
Binary file "/opt/python/build/lib.linux-x86_64-3.14/_ctypes.cpython-314d-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