Python Faulthandler Documentation

Note: This documentation is for the Python faulthandler module available in Python 3.3 and later versions.

The Python faulthandler module is a powerful debugging tool that helps developers diagnose and troubleshoot critical errors in Python applications. This module contains functions to dump Python tracebacks explicitly when a program crashes, times out, or receives specific signals.

Critical errors in Python applications can be difficult to diagnose, especially when they result from segmentation faults, memory access violations, or deadlocks. The faulthandler module addresses these challenges by providing a way to obtain Python tracebacks even in situations where traditional debugging tools might fail.

Crash Diagnostics

Get Python tracebacks for segmentation faults and other fatal errors

Timeout Detection

Dump tracebacks after timeouts to diagnose deadlocks

Signal Handling

Register custom signal handlers to generate diagnostic information

Getting Started

The faulthandler module is part of the Python standard library since version 3.3, so no installation is required. You can simply import it in your code:

Basic setup
import faulthandler

# Enable the fault handler
faulthandler.enable()

This basic setup will cause Python to display a traceback when your program crashes due to:

  • Segmentation faults (SIGSEGV)
  • Floating point exceptions (SIGFPE)
  • Bus errors (SIGBUS)
  • Illegal instructions (SIGILL)
  • Abort signals (SIGABRT)

Environment Variable Setup

You can also enable faulthandler globally without modifying your code by setting the PYTHONFAULTHANDLER environment variable:

export PYTHONFAULTHANDLER=1
python your_script.py
set PYTHONFAULTHANDLER=1
python your_script.py
$env:PYTHONFAULTHANDLER=1
python your_script.py

Basic Usage

The most common way to use faulthandler is to enable it at the beginning of your program to help diagnose crashes:

Enable Functionality

Basic usage example
import faulthandler

# Enable the fault handler
faulthandler.enable()

# Your potentially problematic code here
def cause_segfault():
    # This would typically cause a segmentation fault
    # (Example only - don't run this directly)
    import ctypes
    ctypes.string_at(0)

Traceback Output

When your program encounters a fatal error, faulthandler will print a traceback to stderr before the program terminates. Here's an example of what the output might look like:

Fatal Python error: Segmentation fault

Current thread 0x00007f7a3c39e700 (most recent call first):
  File "example.py", line 8 in cause_segfault
  File "example.py", line 12 in <module>

Segmentation fault

This traceback shows you exactly where in your code the fatal error occurred, making it much easier to diagnose the problem.

Advanced Usage

For more complex scenarios, faulthandler offers additional features to help with debugging:

Writing to a File

You can direct faulthandler output to a file instead of stderr, which is useful for background processes or services:

File output example
# Writing fault tracebacks to a file
import faulthandler

# Open a file in write mode
with open('fault_log.txt', 'w') as f:
    # Enable faulthandler with output directed to the file
    faulthandler.enable(file=f)
    
    # Your application code here

Using Timeouts

The timeout feature is particularly useful for diagnosing deadlocks or code that hangs:

Timeout handler example
# Setting up a timeout handler (useful for deadlocks)
import faulthandler
import time

faulthandler.enable()

# Dump traceback after 30 seconds, repeat every 5 seconds
faulthandler.dump_traceback_later(timeout=30, repeat=True, file=None, exit=False)

# Simulate a deadlock or long-running process
def simulate_deadlock():
    print("Simulating a deadlock...")
    time.sleep(60)  # This will trigger our timeout handler

simulate_deadlock()

# Important: cancel the handler when you're done
faulthandler.cancel_dump_traceback_later()
Note: The timeout feature uses the SIGALRM signal which is not available on Windows. For Windows systems, consider using threading.Timer as an alternative.

Signal Handlers

You can register custom signal handlers to dump tracebacks on demand:

Signal handler example
# Register a user signal to trigger traceback
import faulthandler
import signal

# Enable the fault handler
faulthandler.enable()

# Register the SIGUSR1 signal to dump the traceback
faulthandler.register(signal.SIGUSR1)

# Now you can send SIGUSR1 to your Python process
# to get a traceback dumped to stderr
# On Unix: kill -SIGUSR1 pid_of_python_process

print(f"Process ID: {os.getpid()}")
# Your long-running application code here
while True:
    time.sleep(1)

Real-world Use Case: Web Application Debugging

In a production web application, you might want to enable faulthandler to catch crashes without impacting normal operation:

import faulthandler
import logging
import os
from datetime import datetime

# Create a directory for crash logs if it doesn't exist
os.makedirs('crash_logs', exist_ok=True)

# Create a crash log file with timestamp
timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
crash_log_path = f'crash_logs/crash_{timestamp}.log'

try:
    # Use a dedicated file for fault tracebacks
    crash_file = open(crash_log_path, 'w')
    
    # Enable faulthandler with output directed to this file
    faulthandler.enable(file=crash_file)
    
    # Also register for SIGUSR1 for manual dump trigger
    faulthandler.register(signal.SIGUSR1, file=crash_file)
    
    logging.info(f"Faulthandler enabled, crash logs will be written to {crash_log_path}")
    logging.info(f"Process ID: {os.getpid()}")
    
    # Your web application initialization and serving code here
    
except Exception as e:
    logging.error(f"Failed to set up faulthandler: {e}")

Common Issues

No tracebacks displayed despite enabling faulthandler

This might happen if:

  • Your program is redirecting stderr to a file or pipe
  • The crash is happening in a C extension that doesn't give Python a chance to handle it
  • You're on Windows using certain console configurations

Solution:

Try enabling faulthandler with a specific file output:

with open('crash.log', 'w') as f:
    faulthandler.enable(file=f)

Timeout feature doesn't work

The timeout feature might not work if:

  • You're on Windows (the feature uses SIGALRM which isn't available on Windows)
  • Your code is blocking signals
  • The Python interpreter is completely frozen

Solution:

On Windows, use an alternative approach:

import threading
import faulthandler
import time
import os
import signal

def dump_traceback():
    print("Dumping traceback...")
    # On Windows, we can use os.kill with signal.CTRL_BREAK_EVENT
    if os.name == 'nt':
        os.kill(os.getpid(), signal.CTRL_BREAK_EVENT)
    else:
        # On Unix, we can use SIGUSR1 if registered
        os.kill(os.getpid(), signal.SIGUSR1)

# Enable faulthandler
faulthandler.enable()

# On Unix systems, register SIGUSR1
if os.name != 'nt':
    faulthandler.register(signal.SIGUSR1)

# Set up a timer to trigger the traceback dump
timer = threading.Timer(30.0, dump_traceback)
timer.start()

# Your potentially deadlocking code here
# ...

Incomplete tracebacks in multithreaded applications

By default, faulthandler shows the traceback only for the thread where the fatal error occurred.

Solution:

Make sure to enable all_threads when initializing faulthandler:

faulthandler.enable(file=sys.stderr, all_threads=True)

This will ensure you get tracebacks for all threads, not just the one that crashed.

API Reference

Function Description
enable(file=sys.stderr, all_threads=True)

Enable the fault handler, with optional output file and threading support.

  • file: An open file-like object where tracebacks are written to (default: sys.stderr)
  • all_threads: If True, display tracebacks for all threads (default: True)
disable() Disable the fault handler.
is_enabled() Check if the fault handler is enabled. Returns a bool.
dump_traceback(file=sys.stderr, all_threads=True)

Explicitly dump the current traceback.

  • file: An open file-like object where tracebacks are written to (default: sys.stderr)
  • all_threads: If True, display tracebacks for all threads (default: True)
dump_traceback_later(timeout, repeat=False, file=sys.stderr, exit=False)

Dump the tracebacks of all threads after a timeout.

  • timeout: Delay in seconds before dumping tracebacks
  • repeat: If True, repeat dump every timeout seconds (default: False)
  • file: An open file-like object where tracebacks are written to (default: sys.stderr)
  • exit: If True, exit the process after dumping tracebacks (default: False)
cancel_dump_traceback_later() Cancel the previous dump_traceback_later() call.
register(signum, file=sys.stderr, all_threads=True, chain=False)

Register a handler for the given signal to dump tracebacks.

  • signum: Signal number (e.g., signal.SIGUSR1)
  • file: An open file-like object where tracebacks are written to (default: sys.stderr)
  • all_threads: If True, display tracebacks for all threads (default: True)
  • chain: If True, call the previous signal handler after (default: False)
unregister(signum)

Unregister a handler for the given signal.

  • signum: Signal number (e.g., signal.SIGUSR1)

Additional Resources

Official Documentation

Comprehensive guide covering all functions and features of the module.

View Resource

Debugging Python Crashes

Learn how faulthandler.enable() can help debug scripts that crash Python itself.

View Resource

Debugging a Deadlock

In-depth article showing how to use faulthandler to debug deadlock situations.

View Resource

Python Debugging Workshop

Comprehensive video tutorial covering debugging techniques including faulthandler.

View Resource