O módulo faulthandler ajuda a diagnosticar falhas graves que normalmente encerram o processo antes que o Python consiga produzir um traceback convencional. Ele pode registrar a pilha de todas as threads quando ocorre uma falha de segmentação, abort, erro de barramento, instrução ilegal, estouro de tempo ou sinal solicitado pelo operador. É especialmente útil em aplicações que usam extensões nativas, bibliotecas C, processamento científico, drivers, bindings, serviços longos e testes que travam de forma intermitente.
O módulo não corrige o problema e não substitui um debugger nativo. Seu papel é preservar contexto suficiente para descobrir onde as threads Python estavam no momento da falha. Como o processo pode estar em estado corrompido, a saída é deliberadamente simples, usa recursos mínimos e deve ser enviada para um arquivo ou stream confiável.
Ative o faulthandler
A forma mais direta é chamar faulthandler.enable() no início da aplicação.
import faulthandler
faulthandler.enable()
Por padrão, a saída vai para sys.stderr. Faça a ativação antes de carregar extensões suspeitas ou iniciar várias threads, para que uma falha precoce também seja registrada.
Ative pela variável de ambiente
Em produção, pode ser mais fácil ativar sem alterar o código.
PYTHONFAULTHANDLER=1 python app.pyEssa abordagem ajuda durante incidentes, em containers e em comandos de teste. Ela também evita depender de uma linha que talvez nunca seja executada por causa de uma falha durante imports.
Use a opção -X
O interpretador aceita a opção -X faulthandler.
python -X faulthandler app.pyEla é útil em scripts, jobs, testes isolados e reproduções locais. Registre no runbook como habilitar essa opção para que a equipe não precise descobrir o procedimento durante um incidente.
O que o módulo captura
Em plataformas compatíveis, o módulo instala handlers para sinais fatais como SIGSEGV, SIGFPE, SIGABRT, SIGBUS e SIGILL. A disponibilidade exata depende do sistema operacional e do build do Python.
Esses sinais costumam indicar corrupção de memória, divisão inválida em código nativo, acesso a endereço incorreto, abort explícito ou instrução incompatível. Código Python puro raramente provoca essas condições sozinho; extensões e bibliotecas externas são os suspeitos comuns.
Traceback normal versus falha fatal
Uma exceção Python comum percorre frames, executa finally e pode ser capturada. Uma falha fatal pode interromper o runtime imediatamente. O faulthandler tenta escrever as pilhas sem depender das estruturas complexas usadas pelo traceback normal.
A saída pode ser limitada, não incluir valores locais e mostrar somente nomes de arquivos, funções e linhas. Mesmo assim, a sequência de chamadas costuma revelar o subsistema ativo.
Grave em arquivo
Em serviços, stderr pode ser perdido, truncado ou misturado com muitos logs. Abra um arquivo dedicado e mantenha-o vivo enquanto o handler estiver ativo.
import faulthandler
arquivo = open("falhas-python.log", "a", buffering=1)
faulthandler.enable(file=arquivo, all_threads=True)
Não feche o arquivo enquanto o módulo ainda pode usá-lo. O faulthandler guarda o descritor, não uma promessa de que o objeto será reaberto automaticamente.
Rotação de logs
Se um sistema externo renomeia ou substitui o arquivo, o descritor antigo pode continuar apontando para o inode anterior. Reabra e reconfigure o handler depois da rotação, ou envie a saída para stderr e deixe o runtime de containers coletá-la.
Evite rotacionar o arquivo no meio de um incidente sem entender o comportamento dos descritores.
Inclua todas as threads
O parâmetro all_threads=True registra as pilhas de todas as threads Python disponíveis.
faulthandler.dump_traceback(all_threads=True)
Isso é essencial quando uma thread está bloqueada aguardando outra. A thread que solicita o dump pode não ser a origem do deadlock.
Gere um dump manual
dump_traceback() grava as pilhas sem encerrar o processo.
import faulthandler
faulthandler.dump_traceback()
Use em endpoints administrativos protegidos, comandos internos, watchdogs e testes. Nunca exponha o dump publicamente: caminhos, nomes de funções e detalhes da arquitetura podem ser sensíveis.
Timeout com dump_traceback_later
dump_traceback_later() agenda um dump se a operação ultrapassar um prazo.
faulthandler.dump_traceback_later(
30,
repeat=False,
file=arquivo,
exit=False,
)
try:
executar_operacao()
finally:
faulthandler.cancel_dump_traceback_later()
Esse padrão é valioso para testes que às vezes travam, inicialização lenta, shutdown e chamadas nativas que não retornam.
Repita o dump
Com repeat=True, o módulo produz dumps em intervalos sucessivos.
Comparar várias pilhas ajuda a distinguir um deadlock estático de um processo lento que continua progredindo. Porém, a repetição pode gerar muito volume. Defina retenção e cancele assim que o diagnóstico estiver completo.
Encerre depois do timeout
O parâmetro exit=True solicita saída imediata depois do dump.
Use apenas quando um processo travado deve ser substituído por um supervisor e quando a operação não pode continuar com segurança. A saída abrupta não executa cleanup normal, não faz flush garantido de todos os buffers e pode interromper transações.
Registre um sinal de diagnóstico
Em sistemas Unix, register() pode associar um sinal definido pelo usuário a um dump.
import faulthandler
import signal
faulthandler.register(
signal.SIGUSR1,
all_threads=True,
chain=False,
)
Depois, um operador autorizado pode enviar o sinal ao PID para obter as pilhas sem parar o processo.
Escolha o sinal com cuidado
Não sobrescreva um sinal já usado pela aplicação, servidor, runtime ou sistema de observabilidade. Documente o número e verifique conflitos com handlers existentes.
Em containers, confirme se o sinal chega ao processo correto. Um shell como PID 1 pode interceptar ou não encaminhar sinais.
O parâmetro chain
Quando chain=True, o handler anterior também é chamado depois do dump. Isso permite coexistência com outra ferramenta, mas pode executar lógica não segura em contexto de sinal.
Teste a combinação no mesmo sistema operacional e runtime de produção. Não assuma que dois handlers complexos podem ser encadeados sem efeitos colaterais.
Desregistre o sinal
unregister(signum) remove o handler configurado pelo módulo.
faulthandler.unregister(signal.SIGUSR1)
Faça isso ao descarregar plugins, alterar estratégia de diagnóstico ou encerrar testes que modificam handlers globais.
Verifique se está ativo
is_enabled() informa se os handlers de falhas fatais estão habilitados.
if not faulthandler.is_enabled():
faulthandler.enable()
Essa verificação é útil em bibliotecas, embora a decisão de ativar um handler global normalmente pertença à aplicação.
Não ative silenciosamente em bibliotecas
Uma biblioteca reutilizável não deveria alterar stderr, sinais ou arquivos globais sem consentimento. Ofereça uma função de configuração e deixe o executável decidir.
Handlers globais podem conflitar com notebooks, servidores, test runners e aplicações embarcadas.
Integração com testes
Ative o módulo ao executar testes que envolvem extensões nativas ou concorrência.
python -X faulthandler -m pytestPara um teste que pode travar, agende um dump com prazo um pouco maior que o esperado. O relatório resultante costuma apontar o fixture, lock ou chamada nativa bloqueada.
Use com multiprocessing
Cada processo possui seu próprio runtime e precisa ativar o handler. Um dump no processo pai não mostra automaticamente as threads dos filhos.
def iniciar_worker():
faulthandler.enable()
Configure arquivos separados por PID ou use stderr centralizado para evitar que saídas simultâneas se misturem.
Use com threads
O dump de todas as threads revela locks, filas e operações bloqueantes. Combine com nomes claros de threads para facilitar a leitura.
threading.Thread(
target=worker,
name="importador-clientes",
)
O nome pode aparecer em ferramentas complementares, embora a saída do faulthandler seja centrada nos frames.
Use com concurrent.futures
Pools podem parecer travados quando todos os workers esperam futuros do mesmo executor. Um dump periódico mostra várias threads presas em Future.result().
Leia também o guia de concurrent.futures no Python para evitar deadlocks estruturais.
Use com extensões C
Quando a última linha Python chama uma extensão nativa, o problema pode estar dentro dela. Registre versão da biblioteca, arquitetura, sistema, parâmetros e passos de reprodução.
O traceback Python orienta o debugger nativo para a fronteira correta, mas GDB, LLDB, WinDbg ou ferramentas do fornecedor ainda podem ser necessários.
C stack quando disponível
Versões e builds recentes podem oferecer integração adicional para mostrar a pilha C em determinadas condições. A disponibilidade depende de compilação, plataforma e suporte do runtime.
Trate esse recurso como complemento. Símbolos de debug e binários não removidos melhoram a utilidade da pilha nativa.
Descritores de arquivo
O handler escreve diretamente no descritor associado ao stream. Se o descritor for reutilizado depois que o arquivo for fechado, a saída pode ir para um destino inesperado.
Mantenha ownership claro e feche o arquivo somente depois de desabilitar o módulo ou encerrar o processo.
Desabilite quando necessário
disable() remove os handlers de falhas fatais instalados pelo módulo.
faulthandler.disable()
Isso pode ser necessário em testes de handlers próprios ou aplicações embarcadas. Na maioria dos serviços, deixá-lo ativo tem baixo custo até uma falha.
Segurança dos dumps
Os dumps não incluem intencionalmente todos os valores locais, mas podem revelar caminhos, nomes de clientes, módulos internos e organização do sistema.
Proteja arquivos, limite acesso ao sinal de diagnóstico, defina retenção e remova dados antes de anexar o relatório a um ticket público.
Privacidade e multitenancy
Em um processo que atende vários clientes, as pilhas de todas as threads podem revelar quais operações estão em andamento. Trate o dump como dado operacional sensível.
Evite disponibilizar a funcionalidade por endpoint sem autenticação forte, autorização e auditoria.
Watchdogs
Um watchdog externo pode enviar um sinal de dump antes de reiniciar um processo sem resposta. Essa sequência preserva evidência e automatiza recuperação.
Use dois prazos: primeiro diagnóstico, depois encerramento. Assim o processo tem chance de voltar e o operador recebe contexto se ele permanecer travado.
Deadlock versus lentidão
Um único dump mostra posição; vários dumps mostram movimento. Se as linhas mudam, a aplicação pode estar apenas lenta. Se permanecem idênticas em locks e waits, deadlock ou bloqueio externo é mais provável.
Combine com métricas de CPU, I/O, filas e latência.
Não substitui logging
Logs contam a sequência semântica antes da falha; o faulthandler mostra pilhas no instante crítico. Use ambos.
Inclua IDs de operação e versões nos logs para relacionar o dump a uma request ou job.
Não substitui core dump
Um core dump preserva memória e estado nativo para análise profunda, mas é maior e pode conter segredos. O faulthandler é mais leve e rápido.
Em incidentes difíceis, configure ambos conforme a política de segurança.
Limitações
Se o processo for encerrado com SIGKILL, queda de energia ou finalização externa imediata, nenhum handler executa. Corrupção severa também pode impedir uma saída completa.
O módulo não detecta automaticamente todo deadlock e não mostra o estado interno de bibliotecas nativas.
Teste o diagnóstico
Não espere o incidente real. Crie um ambiente controlado, acione dumps manuais e confirme que o arquivo aparece no local esperado, com permissões e rotação corretas.
Teste também containers, systemd, Windows Services e workers separados.
Erros comuns
Os erros mais frequentes são ativar tarde demais, fechar o arquivo usado pelo handler, acreditar que o timeout interrompe a operação sem exit, registrar um sinal em conflito, expor dumps publicamente, esperar detalhes completos de C e ativar apenas no processo pai.
Conclusão
faulthandler é uma camada simples e valiosa de diagnóstico para crashes, deadlocks e travamentos. Ative-o cedo, preserve a saída em destino confiável, use dumps por sinal ou timeout e capture todas as threads.
Combine os relatórios com logs, métricas e um debugger nativo quando houver extensões C. Consulte a documentação oficial de faulthandler e o artigo sobre dis no Python para investigar o bytecode próximo à falha.







