El módulo faulthandler ayuda a diagnosticar fallos graves que pueden terminar un proceso antes de que Python produzca un traceback normal. Puede volcar las pilas cuando ocurre una segmentation fault, abort, bus error, instrucción ilegal, timeout o señal solicitada por un operador. Es especialmente útil en aplicaciones con extensiones nativas, bibliotecas científicas, drivers, bindings, servicios de larga duración, multiprocessing y tests que se bloquean de forma intermitente.
El módulo no corrige el problema y no sustituye un debugger nativo. Su objetivo es conservar contexto suficiente para mostrar dónde estaban las threads de Python cuando el proceso falló o dejó de progresar. Como el runtime puede encontrarse en un estado corrupto, la salida es deliberadamente simple y debe escribirse en un archivo o stream confiable.
Activa faulthandler
La forma más directa es llamar a faulthandler.enable() al inicio de la aplicación.
import faulthandler
faulthandler.enable()
Por defecto, la salida va a sys.stderr. Actívalo antes de cargar extensiones sospechosas o iniciar múltiples threads para capturar fallos tempranos.
Activa mediante variable de entorno
En producción puede ser necesario habilitar el diagnóstico sin cambiar el código.
PYTHONFAULTHANDLER=1 python app.pyEsto resulta práctico en containers, jobs, comandos de test e incidentes. También ayuda cuando el fallo ocurre durante imports antes de que la inicialización normal alcance la configuración.
Usa la opción -X
El intérprete acepta -X faulthandler.
python -X faulthandler app.pyDocumenta esta opción en el runbook operativo. Una herramienta de diagnóstico pierde valor si el equipo necesita investigarla durante una caída.
Qué fallos captura
En plataformas compatibles, el módulo instala handlers para señales fatales como SIGSEGV, SIGFPE, SIGABRT, SIGBUS y SIGILL. La disponibilidad exacta depende del sistema operativo y del build de Python.
Estas señales suelen indicar corrupción de memoria, aritmética nativa inválida, abort explícito, dirección incorrecta o instrucción incompatible. El código Python puro rara vez las provoca directamente; las extensiones y bibliotecas externas son sospechosos comunes.
Dump fatal frente a traceback normal
Una excepción Python normal recorre frames, ejecuta bloques finally y puede capturarse. Un fallo nativo fatal puede detener el runtime inmediatamente. Faulthandler intenta escribir las pilas con una implementación restringida que no depende del mecanismo normal de traceback.
El resultado puede omitir variables locales y mostrar únicamente archivos, funciones y líneas. Aun así, esa secuencia suele identificar el subsistema activo.
Escribe en un archivo dedicado
El stderr de un servicio puede perderse, truncarse o mezclarse con muchos logs. Abre un archivo dedicado y mantenlo vivo mientras el handler esté activo.
import faulthandler
archivo = open("fallos-python.log", "a", buffering=1)
faulthandler.enable(file=archivo, all_threads=True)
No cierres el archivo mientras faulthandler pueda utilizarlo. El módulo conserva el descriptor y no abre automáticamente un reemplazo.
Rotación de logs
Si un rotador externo renombra o sustituye el archivo, el descriptor antiguo puede seguir apuntando al inode anterior. Reabre el destino y configura de nuevo el handler, o utiliza stderr y deja que el runtime de containers recoja la salida.
Prueba la estrategia exacta de rotación en el mismo entorno de producción.
Incluye todas las threads
El parámetro all_threads=True incluye todas las threads Python disponibles.
faulthandler.dump_traceback(all_threads=True)
Esto es esencial cuando una thread espera a otra. La thread que solicita el dump puede no ser la responsable del deadlock.
Genera un dump manual
dump_traceback() escribe las pilas sin terminar el proceso.
import faulthandler
faulthandler.dump_traceback()
Úsalo en comandos administrativos protegidos, watchdogs internos y tests controlados. Nunca expongas el dump públicamente porque las rutas y la arquitectura pueden ser sensibles.
Programa un dump por timeout
dump_traceback_later() agenda una captura cuando una operación supera un plazo.
faulthandler.dump_traceback_later(
30,
repeat=False,
file=archivo,
exit=False,
)
try:
ejecutar_operacion()
finally:
faulthandler.cancel_dump_traceback_later()
Este patrón es útil para tests que se cuelgan, startup lento, shutdown bloqueado y llamadas nativas que no vuelven.
Repite los dumps
Con repeat=True, el módulo escribe pilas en intervalos sucesivos.
Varias capturas permiten diferenciar un deadlock estático de un proceso lento que todavía progresa. La repetición puede generar mucho volumen, así que define retención y cancela el timer al terminar.
Finaliza después del timeout
El parámetro exit=True solicita una salida inmediata después del dump.
Úsalo únicamente cuando un supervisor pueda sustituir el proceso y continuar sea inseguro. La salida abrupta omite cleanup normal, puede dejar buffers sin flush e interrumpir transacciones.
Registra una señal operativa
En sistemas Unix, register() puede asociar un dump a una señal de usuario.
import faulthandler
import signal
faulthandler.register(
signal.SIGUSR1,
all_threads=True,
chain=False,
)
Un operador autorizado puede enviar la señal al PID y obtener las pilas sin detener el proceso.
Elige la señal con cuidado
No sobrescribas una señal utilizada por la aplicación, servidor, runtime o agente de observabilidad. Documenta la señal y comprueba conflictos.
Dentro de containers, verifica que llegue al proceso Python. Un shell como PID 1 puede no reenviarla.
El parámetro chain
Con chain=True, el handler anterior también se ejecuta después del dump. Esto puede conservar otra herramienta de diagnóstico, pero también activar lógica insegura en contexto de señal.
Prueba la combinación en la misma plataforma y versión desplegada.
Desregistra una señal
unregister(signum) elimina el handler configurado por el módulo.
faulthandler.unregister(signal.SIGUSR1)
Úsalo al descargar plugins, cambiar la estrategia o limpiar tests que modifican señales globales.
Comprueba si está activo
is_enabled() indica si los handlers fatales están habilitados.
if not faulthandler.is_enabled():
faulthandler.enable()
La comprobación sirve en ejecutables y frameworks. Una biblioteca reutilizable debería dejar la decisión global a la aplicación.
No lo actives ocultamente en bibliotecas
Una biblioteca no debería modificar stderr, señales o archivos globales sin consentimiento. Ofrece una función explícita de configuración.
Los handlers globales pueden entrar en conflicto con notebooks, test runners, servidores e intérpretes embebidos.
Integración con tests
Activa el módulo al ejecutar tests con extensiones nativas, threads o subprocesses.
python -X faulthandler -m pytestPara un test que puede bloquearse, agenda un timeout algo mayor que la duración esperada. Las pilas suelen señalar el fixture, lock, queue o llamada nativa detenida.
Multiprocessing
Cada proceso posee su propio intérprete y debe activar faulthandler por separado. Un dump del padre no muestra automáticamente las threads de los hijos.
def iniciar_worker():
faulthandler.enable()
Usa archivos separados por PID o stderr centralizado para evitar salidas mezcladas.
Threads
Los dumps de todas las threads revelan locks, condiciones, queues e I/O bloqueante. Asigna nombres claros a las threads para mejorar logs y debugger.
threading.Thread(
target=worker,
name="importador-clientes",
)
Faulthandler se centra en frames, pero el naming consistente mejora el resto de la evidencia.
Concurrent futures
Un pool puede parecer congelado cuando todos los workers esperan otro future del mismo executor. Dumps repetidos muestran muchas threads bloqueadas en Future.result().
Consulta concurrent.futures en Python para prevenir deadlocks estructurales.
Extensiones nativas
Si el último frame Python llama a una extensión, el fallo puede estar en C, C++, Rust, Fortran, runtime de GPU o driver. Registra versiones, arquitectura, sistema operativo, entradas y pasos de reproducción.
La pila Python identifica la frontera, pero quizá necesites GDB, LLDB, WinDbg, sanitizers o herramientas del proveedor.
Pila C cuando está disponible
Versiones y builds recientes pueden ofrecer información adicional de la pila nativa en entornos compatibles. Depende de la plataforma, opciones de compilación y símbolos de debug.
Trata esa salida como complemento. Binarios con símbolos mejoran mucho el diagnóstico.
Lifetime del descriptor
El módulo escribe mediante el descriptor asociado al stream. Si cierras el archivo y ese número se reutiliza, la salida podría dirigirse a otro destino.
Mantén ownership explícito y cierra solamente después de desactivar el handler o finalizar el proceso.
Desactiva cuando sea necesario
disable() elimina los handlers fatales instalados por el módulo.
faulthandler.disable()
Puede ser necesario en tests de handlers propios o aplicaciones embebidas. En servicios normales, mantenerlo activo tiene poco coste.
Seguridad de los dumps
Aunque se omiten muchos valores locales, los dumps pueden revelar rutas, nombres internos, módulos específicos de clientes y arquitectura.
Protege los archivos, limita el acceso a señales, aplica retención y sanitiza antes de publicar un informe.
Privacidad en servicios multi-tenant
Un dump de todas las threads puede mostrar operaciones de varios clientes al mismo tiempo. Trátalo como dato operativo sensible.
No expongas la generación mediante endpoint sin autenticación fuerte, autorización y auditoría.
Watchdogs
Un watchdog externo puede pedir un dump antes de reiniciar un proceso sin respuesta. Esto conserva evidencia y permite recuperación automática.
Usa dos deadlines: primero diagnóstico y después terminación. El proceso tiene oportunidad de volver y el operador obtiene contexto si sigue bloqueado.
Deadlock frente a lentitud
Un dump muestra posición; varios muestran movimiento. Si las líneas cambian, quizá el proceso solo sea lento. Frames idénticos en waits y locks sugieren deadlock o bloqueo permanente.
Combina las pilas con métricas de CPU, I/O, queues, memoria y latencia.
No sustituye logging
Los logs explican la secuencia semántica anterior; faulthandler muestra posiciones en el instante crítico. Utiliza ambos.
Incluye IDs de operación y versiones para relacionar el dump con una request o job.
No sustituye un core dump
Un core dump conserva memoria y estado nativo para análisis profundo, pero es grande y puede contener secretos. Faulthandler es ligero y rápido.
Para incidentes difíciles, configura ambos según la política de seguridad.
Limitaciones
Ningún handler se ejecuta después de SIGKILL, corte de energía o algunas terminaciones inmediatas. Una corrupción severa también puede impedir una salida completa.
El módulo no detecta automáticamente todos los deadlocks ni explica el estado interno de bibliotecas nativas.
Prueba el camino de diagnóstico
No esperes un crash real. Genera dumps manuales en un entorno controlado y verifica destino, permisos, rotación, recogida y alertas.
Repite en containers, systemd, Windows Services y workers separados.
Errores comunes
Los errores frecuentes son activarlo demasiado tarde, cerrar el archivo, creer que un timeout detiene la operación sin exit, registrar una señal en conflicto, exponer dumps, esperar detalles nativos completos y activarlo solo en el padre.
Conclusión
faulthandler es una capa simple y valiosa para diagnosticar crashes, deadlocks y bloqueos. Actívalo pronto, conserva la salida en un destino fiable, usa señales o timeouts y captura todas las threads.
Combina el informe con logs, métricas y debuggers nativos cuando existan extensiones C. Consulta la documentación oficial de faulthandler y dis en Python para inspeccionar bytecode cercano al fallo.







