faulthandler no Python: diagnostique crashes

Publicado em: 27/08/2026
Tempo de leitura: 10 minutos
A developer typing code on a laptop with a Python book beside in an office.

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.py

Essa 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.py

Ela é ú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 pytest

Para 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.

Compartilhe:

Facebook
WhatsApp
Twitter
LinkedIn

Conteúdo do artigo

    Artigos relacionados

    Código Python em tela representando EnumDict e enumerações avançadas
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    EnumDict: personalize Enums com validação

    Aprenda EnumDict no Python para personalizar EnumType, validar membros e criar enumerações avançadas com segurança.

    Ler mais

    Tempo de leitura: 5 minutos
    11/10/2026
    Rack de servidores representando balanceamento de conexões com SO_REUSEPORT_LB no Python
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    SO_REUSEPORT_LB: distribua conexões entre workers

    Aprenda SO_REUSEPORT_LB no Python para distribuir conexões entre múltiplos workers com segurança, testes e portabilidade.

    Ler mais

    Tempo de leitura: 6 minutos
    11/10/2026
    Código Python assíncrono em notebook para inspect.markcoroutinefunction
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    markcoroutinefunction: identifique wrappers async

    Aprenda inspect.markcoroutinefunction no Python para identificar wrappers assíncronos, integrar frameworks e evitar detecção incorreta de corrotinas.

    Ler mais

    Tempo de leitura: 6 minutos
    10/10/2026
    Código Python para percorrer pastas e arquivos com Path.walk
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    Path.walk: percorra diretórios com segurança

    Aprenda Path.walk no Python para percorrer diretórios, filtrar arquivos, tratar erros e controlar a travessia com segurança.

    Ler mais

    Tempo de leitura: 6 minutos
    10/10/2026
    Depuração de processo Python em terminal com código
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    pdb -p: depure processos Python em execução

    Aprenda a anexar o pdb a um processo Python em execução, inspecionar pilhas e diagnosticar travamentos com segurança.

    Ler mais

    Tempo de leitura: 6 minutos
    09/10/2026
    Código Python e representação de frações numéricas
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    fractions.from_number: converta números em frações

    Aprenda fractions.from_number no Python para converter números em frações exatas, controlar precisão e evitar arredondamentos inesperados.

    Ler mais

    Tempo de leitura: 5 minutos
    09/10/2026