faulthandler module : Dump the Python traceback
General
Content: functions to dump Python tracebacks explicitly, on a fault, after a timeout, or on a user signal.
Signals/Faults handled: SIGSEGV, SIGFPE, SIGABRT, SIGBUS, SIGILL
Warning:
The fault handler is called on catastrophic cases and therefore can only use signal-safe functions (e.g. it cannot allocate memory on the heap). Because
of this limitation traceback dumping is minimal compared to normal Python tracebacks.
Not exhaustive :
– only ASCII
– limited to 500 characters
– only the filename, the function name and the line number are displayed. (no source code)
How to enable it?
We have two ways:
– Call faulthandler.enable()
.
– setting the PYTHONFAULTHANDLER
environment variable or by using the -X faulthandler
command line option.
Where the faults are traced?
By default, the Python traceback is written to sys.stderr.
A log file can alternatively be passed to faulthandler.enable()
.
Dumping the traceback
Dump the tracebacks of all threads into file.
If all_threads
is False
, dump only the current thread.
faulthandler.dump_traceback(file=sys.stderr, all_threads=True)
Dumping the tracebacks after a timeout
Dump the tracebacks of all threads, after a timeout of timeout seconds, or every timeout seconds if repeat
is True
.
If exit is True
, call _exit()
with status=1 after dumping the tracebacks:
faulthandler.dump_traceback_later(timeout, repeat=False, file=sys.stderr, exit=False)
Cancel the last call to dump_traceback_later()
:
faulthandler.cancel_dump_traceback_later()
Dumping the traceback on a user signal
Works only on linux.
faulthandler Examples
faulthandler with signal
import faulthandler import signal def a(): # We raise an illegal instruction signal. signal.raise_signal(signal.SIGILL) faulthandler.enable() a() |
Output:
Fatal Python error: Illegal instruction Current thread 0x00005154 (most recent call first): File "C:\programmation\workspace-python\python_blog_examples\faulthandler_and_sys_hook\faulthandler_with_signal.py", line 7 in a File "C:\programmation\workspace-python\python_blog_examples\faulthandler_and_sys_hook\faulthandler_with_signal.py", line 12 in <module> |
print threads dump with faulthandler.dump_traceback()
import faulthandler import sys from threading import Thread from time import sleep def a(): i: int = 0 while True: i += 1 sleep(0.25) def b(): sleep(5) faulthandler.enable() Thread(daemon=True, name='a', target=lambda: a()).start() Thread(daemon=True, name='b', target=lambda: b()).start() faulthandler.dump_traceback() sys.exit() |
Output:
Thread 0x00002224 (most recent call first): File "C:\programmation\workspace-python\python_blog_examples\faulthandler_and_sys_hook\faulthandler_dump_traceback_of_all_threads.py", line 15 in b File "C:\programmation\workspace-python\python_blog_examples\faulthandler_and_sys_hook\faulthandler_dump_traceback_of_all_threads.py", line 21 in <lambda> File "C:\Users\david\AppData\Local\Programs\Python\Python310\lib\threading.py", line 953 in run File "C:\Users\david\AppData\Local\Programs\Python\Python310\lib\threading.py", line 1016 in _bootstrap_inner File "C:\Users\david\AppData\Local\Programs\Python\Python310\lib\threading.py", line 973 in _bootstrap Thread 0x00003a9c (most recent call first): File "C:\programmation\workspace-python\python_blog_examples\faulthandler_and_sys_hook\faulthandler_dump_traceback_of_all_threads.py", line 11 in a File "C:\programmation\workspace-python\python_blog_examples\faulthandler_and_sys_hook\faulthandler_dump_traceback_of_all_threads.py", line 20 in <lambda> File "C:\Users\david\AppData\Local\Programs\Python\Python310\lib\threading.py", line 953 in run File "C:\Users\david\AppData\Local\Programs\Python\Python310\lib\threading.py", line 1016 in _bootstrap_inner File "C:\Users\david\AppData\Local\Programs\Python\Python310\lib\threading.py", line 973 in _bootstrap Current thread 0x000049d4 (most recent call first): File "C:\programmation\workspace-python\python_blog_examples\faulthandler_and_sys_hook\faulthandler_dump_traceback_of_all_threads.py", line 22 in <module> |
repeat print threads dump with dump_traceback_later()
import faulthandler from threading import Thread from time import sleep def a(): i: int = 0 while True: i += 1 sleep(0.25) def b(): sleep(5) faulthandler.enable() thread_a = Thread(daemon=True, name='a', target=lambda: a()) thread_a.start() thread_b = Thread(daemon=True, name='b', target=lambda: b()) thread_b.start() faulthandler.dump_traceback_later(repeat=True, timeout=2) thread_a.join() thread_b.join() |
Output:
Timeout (0:00:02)! Thread 0x00004870 (most recent call first): File "C:\programmation\workspace-python\python_blog_examples\faulthandler_and_sys_hook\faulthandler_dump_traceback_later.py", line 14 in b File "C:\programmation\workspace-python\python_blog_examples\faulthandler_and_sys_hook\faulthandler_dump_traceback_later.py", line 21 in <lambda> File "C:\Users\david\AppData\Local\Programs\Python\Python310\lib\threading.py", line 953 in run File "C:\Users\david\AppData\Local\Programs\Python\Python310\lib\threading.py", line 1016 in _bootstrap_inner File "C:\Users\david\AppData\Local\Programs\Python\Python310\lib\threading.py", line 973 in _bootstrap Thread 0x00002c64 (most recent call first): File "C:\programmation\workspace-python\python_blog_examples\faulthandler_and_sys_hook\faulthandler_dump_traceback_later.py", line 10 in a File "C:\programmation\workspace-python\python_blog_examples\faulthandler_and_sys_hook\faulthandler_dump_traceback_later.py", line 19 in <lambda> File "C:\Users\david\AppData\Local\Programs\Python\Python310\lib\threading.py", line 953 in run File "C:\Users\david\AppData\Local\Programs\Python\Python310\lib\threading.py", line 1016 in _bootstrap_inner File "C:\Users\david\AppData\Local\Programs\Python\Python310\lib\threading.py", line 973 in _bootstrap Thread 0x000053d8 (most recent call first): File "C:\Users\david\AppData\Local\Programs\Python\Python310\lib\threading.py", line 1116 in _wait_for_tstate_lock File "C:\Users\david\AppData\Local\Programs\Python\Python310\lib\threading.py", line 1096 in join File "C:\programmation\workspace-python\python_blog_examples\faulthandler_and_sys_hook\faulthandler_dump_traceback_later.py", line 24 in <module> Timeout (0:00:02)! Thread 0x00004870 (most recent call first): File "C:\programmation\workspace-python\python_blog_examples\faulthandler_and_sys_hook\faulthandler_dump_traceback_later.py", line 14 in b File "C:\programmation\workspace-python\python_blog_examples\faulthandler_and_sys_hook\faulthandler_dump_traceback_later.py", line 21 in <lambda> File "C:\Users\david\AppData\Local\Programs\Python\Python310\lib\threading.py", line 953 in run File "C:\Users\david\AppData\Local\Programs\Python\Python310\lib\threading.py", line 1016 in _bootstrap_inner File "C:\Users\david\AppData\Local\Programs\Python\Python310\lib\threading.py", line 973 in _bootstrap Thread 0x00002c64 (most recent call first): File "C:\programmation\workspace-python\python_blog_examples\faulthandler_and_sys_hook\faulthandler_dump_traceback_later.py", line 10 in a File "C:\programmation\workspace-python\python_blog_examples\faulthandler_and_sys_hook\faulthandler_dump_traceback_later.py", line 19 in <lambda> File "C:\Users\david\AppData\Local\Programs\Python\Python310\lib\threading.py", line 953 in run File "C:\Users\david\AppData\Local\Programs\Python\Python310\lib\threading.py", line 1016 in _bootstrap_inner File "C:\Users\david\AppData\Local\Programs\Python\Python310\lib\threading.py", line 973 in _bootstrap Thread 0x000053d8 (most recent call first): File "C:\Users\david\AppData\Local\Programs\Python\Python310\lib\threading.py", line 1116 in _wait_for_tstate_lock File "C:\Users\david\AppData\Local\Programs\Python\Python310\lib\threading.py", line 1096 in join File "C:\programmation\workspace-python\python_blog_examples\faulthandler_and_sys_hook\faulthandler_dump_traceback_later.py", line 24 in <module> Timeout (0:00:02)! Thread 0x00002c64 (most recent call first): File "C:\programmation\workspace-python\python_blog_examples\faulthandler_and_sys_hook\faulthandler_dump_traceback_later.py", line 10 in a...... |
Sys hooks
sys.excepthook(type, value, traceback)
When an exception is raised and uncaught, before the program exits the interpreter calls sys.excepthook
with three arguments, the exception
class, exception instance, and a traceback object.
By default, the function prints out a given traceback and exception to sys.stderr.
We can customize this behavior by assigning another three-argument function to sys.excepthook
.
Sys hooks Examples
excepthook example with standard out
import sys import traceback from types import TracebackType def handle_exception(exc_type, exc_value, exc_traceback: TracebackType): if issubclass(exc_type, KeyboardInterrupt): sys.__excepthook__(exc_type, exc_value, exc_traceback) return print('Uncaught exception:') print('Type:', exc_type) print('Value:', exc_value) # We can use the first or the second method. The result is almost the same. # traceback.print_tb(exc_traceback) traceback.print_exception(etype=None, value=exc_value, tb=exc_traceback) def main(): invalid = 'a'[1] if __name__ == '__main__': main() |
Output:
Traceback (most recent call last): File "C:\programmation\workspace-python\python_blog_examples\faulthandler_and_sys_hook\excepthook_example_with_standard_out.py", line 24, in <module> main() File "C:\programmation\workspace-python\python_blog_examples\faulthandler_and_sys_hook\excepthook_example_with_standard_out.py", line 20, in main invalid = 'a'[1] IndexError: string index out of range |
excepthook example with logging
import logging import sys logger: logging.Logger def handle_exception(exc_type, exc_value, exc_traceback): if issubclass(exc_type, KeyboardInterrupt): sys.__excepthook__(exc_type, exc_value, exc_traceback) return logger.error(f"Uncaught exception : {exc_type}", exc_info=(exc_type, exc_value, exc_traceback)) sys.excepthook = handle_exception def main(): global logger logging.basicConfig(level=logging.INFO, format= '%(asctime)-15s - %(threadName)s - %(levelname)s : %(name)s.%(funcName)s %(message)s') logger = logging.getLogger('excepthook_example_with_logging') invalid = 'a'[1] if __name__ == '__main__': main() |
Output:
2023-04-14 13:54:42,266 - MainThread - ERROR : excepthook_example_with_logging.handle_exception Uncaught exception : <class 'IndexError'> Traceback (most recent call last): File "C:\programmation\workspace-python\python_blog_examples\faulthandler_and_sys_hook\excepthook_example_with_logging.py", line 27, in <module> main() File "C:\programmation\workspace-python\python_blog_examples\faulthandler_and_sys_hook\excepthook_example_with_logging.py", line 23, in main invalid = 'a'[1] IndexError: string index out of range |