Habilitando a depuração post-mortem
Tratamento de exceções do modo de usuário
Exceções e pontos de interrupção
Os erros de aplicativo mais comuns são chamados de exceções. Isso inclui violações de acesso, erros de divisão por zero, estouros numéricos, exceções CLR e muitos outros tipos de erros. Os aplicativos também podem causar interrupções de ponto de interrupção. Isso ocorre quando o Windows não consegue executar o aplicativo (por exemplo, quando um módulo necessário não pode ser carregado) ou quando um ponto de interrupção é encontrado. Os pontos de interrupção podem ser inseridos no código por um depurador ou invocados por meio de uma função como DebugBreak.
Precedência de manipuladores de exceção
Com base nos valores de configuração e em quais depuradores estão ativos, o Windows lida com erros no modo de usuário de várias maneiras. A sequência a seguir mostra a precedência usada para o tratamento de erros do modo de usuário:
Se um depurador de modo de usuário estiver anexado ao processo de falha, todos os erros farão com que o destino entre nesse depurador.
Enquanto o depurador do modo de usuário estiver anexado, nenhum outro método de tratamento de erros será usado – mesmo que o comando gn (Go With Exception Not Handled) seja usado.
Se nenhum depurador de modo de usuário estiver anexado e o código em execução tiver suas próprias rotinas de tratamento de exceção (por exemplo, try - exceto), essa rotina de tratamento de exceção tentará lidar com o erro.
Se nenhum depurador de modo de usuário estiver anexado e Windows tiver uma conexão de depuração de kernel aberta e o erro for uma interrupção de ponto de interrupção, Windows tentará entrar em contato com o depurador de kernel.
As conexões de depuração do kernel devem ser abertas durante o processo de inicialização do Windows. Se você quiser impedir que uma interrupção do modo de usuário entre no depurador de kernel, poderá usar o utilitário KDbgCtrl com o parâmetro -du . Para obter detalhes sobre como configurar conexões de depuração de kernel e como usar KDbgCtrl, consulte Configurando para depuração.
No depurador de kernel, você pode usar gh (Go With Exception Handled) para desconsiderar o erro e continuar executando o destino. Você pode usar gn (Go With Exception Not Handled) para ignorar o depurador de kernel e ir para a etapa 4.
Se as condições nas etapas 1, 2 e 3 não se aplicarem, o Windows ativará uma ferramenta de depuração configurada nos valores do Registro AeDebug. Qualquer programa pode ser selecionado com antecedência como a ferramenta a ser usada nessa situação. O programa escolhido é chamado de depurador post-mortem.
Se as condições nas etapas 1, 2 e 3 não se aplicarem e não houver nenhum depurador post-mortem registrado, o WER (Relatório de Erros do Windows) exibirá uma mensagem e fornecerá soluções, se houver alguma disponível. O WER também grava um arquivo de despejo de memória se os valores apropriados forem definidos no Registro. Para obter mais informações, consulte Usando o WER e coletando despejos no modo de usuário.
Função DebugBreak
Se um depurador post-mortem tiver sido instalado, você poderá interromper deliberadamente o depurador de um aplicativo de modo de usuário chamando a função DebugBreak .
Especificando um depurador post-mortem
Esta seção descreve como configurar ferramentas como o WinDbg como o depurador post-mortem. Depois de configurado, o depurador post-mortem será iniciado automaticamente sempre que um aplicativo falhar.
Chaves do Registro do Depurador Post Mortem
O WER (Relatório de Erros do Windows) cria o processo do depurador post-mortem usando os valores definidos na chave do Registro AeDebug.
HKLM\Software\Microsoft\Windows NT\CurrentVersion\AeDebug
Há dois valores primários do Registro de interesse, Depurador e Automático. O valor do Registro do Depurador especifica a linha de comando para o depurador post-mortem. O valor do Registro Automático especifica se o depurador post-mortem é iniciado automaticamente ou se uma caixa de mensagem de confirmação é apresentada primeiro.
Depurador (REG_SZ)
Esse valor REG_SZ especifica o depurador que manipulará a depuração post-mortem.
O caminho completo para o depurador deve ser listado, a menos que o depurador esteja localizado em um diretório que esteja no caminho padrão.
A linha de comando é gerada a partir da cadeia de caracteres do depurador por meio de uma chamada de estilo printf que inclui 3 parâmetros. Embora a ordem seja fixa, não há necessidade de usar nenhum ou todos os parâmetros disponíveis.
DWORD (%ld) - ID do processo de destino.
DWORD (%ld) - Identificador de evento duplicado no processo do depurador post-mortem. Se o depurador post-mortem sinalizar o evento, o WER continuará o processo de destino sem esperar que o depurador post-mortem seja encerrado. O evento só deve ser sinalizado se o problema tiver sido resolvido. Se o depurador post-mortem for encerrado sem sinalizar o evento, o WER continuará a coleta de informações sobre os processos de destino.
void* (%p) - Endereço de uma estrutura JIT_DEBUG_INFO alocada no espaço de endereço do processo de destino. A estrutura contém informações e contexto adicionais de exceção.
Auto (REG_SZ) Este valor REG_SZ é sempre 0 ou 1.
Se Auto for definido como 0, uma caixa de mensagem de confirmação será exibida antes do início do processo de depuração post-mortem.
Se Auto for definido como 1, o depurador post-mortem será criado imediatamente.
Ao editar manualmente o Registro, faça-o com muito cuidado, pois alterações inadequadas no Registro podem não permitir que o Windows inicialize.
Exemplo de uso da linha de comando
Muitos depuradores post-mortem usam uma linha de comando que inclui as opções -p e -e para indicar que os parâmetros são um PID e um Evento (respectivamente). Por exemplo, instalar o WinDbg via windbg.exe -I
cria os seguintes valores:
Debugger = "<Path>\WinDbg -p %ld -e %ld -g"
Auto = 1
Há flexibilidade em como os parâmetros WER %ld %ld %p podem ser usados. Por exemplo. não há necessidade de especificar nenhuma opção ao redor ou entre os parâmetros do WER. Por exemplo, instalar o Windows Sysinternals ProcDump usando procdump.exe -i
cria os seguintes valores sem opções entre os parâmetros WER %ld %ld %p:
Debugger = "<Path>\procdump.exe" -accepteula -j "c:\Dumps" %ld %ld %p
Auto = 1
Depuradores de 32 e 64 bits
Em uma plataforma de 64 bits, os valores do Registro Depurador (REG_SZ) e Automático (REG_SZ) são definidos individualmente para aplicativos de 64 bits e 32 bits. Uma chave adicional do Windows no Windows (WOW) é usada para armazenar os valores de depuração post mortem do aplicativo de 32 bits.
HKLM\Software\Wow6432Node\Microsoft\Windows NT\CurrentVersion\AeDebug
Em uma plataforma de 64 bits, use um depurador post-mortem de 32 bits para processos de 32 bits e um depurador de 64 bits para processos de 64 bits. Isso evita que um depurador de 64 bits se concentre nos threads WOW64, em vez dos threads de 32 bits, em um processo de 32 bits.
Para muitos depuradores post-mortem, incluindo os depuradores post-mortem das Ferramentas de Depuração para Windows, isso envolve a execução do comando de instalação duas vezes; uma vez com a versão x86 e uma vez com a versão x64. Por exemplo, para usar o WinDbg como o depurador post-mortem interativo, o windbg.exe -I
comando seria executado duas vezes, uma para cada versão.
Instalação de 64 bits:
C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\windbg.exe –I
Isso atualiza a chave do Registro com esses valores.
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AeDebug
Debugger = "C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\windbg.exe" -p %ld -e %ld –g
Instalação de 32 bits:
C:\Program Files (x86)\Windows Kits\10\Debuggers\x86\windbg.exe –I
Isso atualiza a chave do Registro com esses valores.
HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows NT\CurrentVersion\AeDebug
Debugger = "C:\Program Files (x86)\Windows Kits\10\Debuggers\x86\windbg.exe" -p %ld -e %ld –g
Configurando depuradores post mortem
Ferramentas de depuração para Windows
Todos os depuradores das Ferramentas de Depuração para Windows dão suporte à definição como o depurador post-mortem. O comando install pretende que o processo seja depurado interativamente.
WinDbg
Para definir o depurador post-mortem como WinDbg, execute windbg -I
. (O I
deve ser maiúsculo.) Esse comando exibirá uma mensagem de sucesso ou falha depois de ser usado. Para trabalhar com aplicativos de 32 e 64 bits, execute o comando para os depuradores de 64 e 32.
C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\windbg.exe –I
C:\Program Files (x86)\Windows Kits\10\Debuggers\x86\windbg.exe –I
É assim que a entrada do Registro AeDebug será configurada quando windbg -I
for executada.
Debugger = "<Path>\WinDbg -p %ld -e %ld -g"
Auto = 1
Nos exemplos, <Path> é o diretório em que o depurador está localizado.
Os parâmetros -p e -e passam a ID do processo e o evento, conforme discutido anteriormente.
O -g passa o comando g (Go) para WinDbg e continua a execução da instrução atual.
Observação Há um problema significativo ao passar o comando g (Go). O problema com essa abordagem é que as exceções nem sempre se repetem, normalmente, devido a uma condição transitória que não existe mais quando o código é reiniciado. Para obter mais informações sobre esse problema, consulte .jdinfo (Usar JIT_DEBUG_INFO).
Para evitar esse problema, use .jdinfo ou .dump /j. Essa abordagem permite que o depurador esteja no contexto da falha de código de interesse. Para obter mais informações, consulte Depuração JIT (Just In Time) mais adiante neste tópico.
CDB
Para definir o depurador post-mortem como CDB, execute cdb -iae (Instalar AeDebug) ou cdb -iaec KeyString (Instalar AeDebug com Comando).
C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\cdb.exe -iae
C:\Program Files (x86)\Windows Kits\10\Debuggers\x86\cdb.exe -iae
Quando o parâmetro -iaec é usado, KeyString especifica uma cadeia de caracteres a ser acrescentada ao final da linha de comando usada para iniciar o depurador post-mortem. Se KeyString contiver espaços, ele deverá ser colocado entre aspas.
C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\cdb.exe -iaec [KeyString]
C:\Program Files (x86)\Windows Kits\10\Debuggers\x86\cdb.exe -iaec [KeyString]
Esse comando não exibirá nada se for bem-sucedido e uma mensagem de erro se falhar.
NTSD
Para definir o depurador post-mortem como NTSD, execute ntsd -iae (Instalar AeDebug) ou ntsd -iaec KeyString (Instalar AeDebug com Comando).
C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\ntsd.exe -iae
C:\Program Files (x86)\Windows Kits\10\Debuggers\x86\ntsd.exe -iae
Quando o parâmetro -iaec é usado, KeyString especifica uma cadeia de caracteres a ser acrescentada ao final da linha de comando usada para iniciar o depurador post-mortem. Se KeyString contiver espaços, ele deverá ser colocado entre aspas.
C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\ntsd.exe -iaec [KeyString]
C:\Program Files (x86)\Windows Kits\10\Debuggers\x86\ntsd.exe -iaec [KeyString]
Esse comando não exibirá nada se for bem-sucedido e um erro em uma nova janela do console em caso de falha.
Observação Como os parâmetros -p %ld -e %ld -g sempre aparecem primeiro na linha de comando do depurador post-mortem, você não deve usar a opção -iaec para especificar o parâmetro -server porque -server não funcionará a menos que apareça primeiro na linha de comando. Para instalar um depurador post-mortem que inclua esse parâmetro, você deve editar o registro manualmente.
Depurador JIT do Visual Studio
Se o Visual Studio tiver sido instalado, vsjitdebugger.exe será registrado como o depurador post mortem. O Depurador JIT do Visual Studio pretende que o processo seja depurado interativamente.
Debugger = "C:\WINDOWS\system32\vsjitdebugger.exe" -p %ld -e %ld
Se o Visual Studio for atualizado ou reinstalado, essa entrada será reescrita, substituindo todos os valores alternativos definidos.
Window Sysinternals ProcDump
O utilitário ProcDump do Windows Sysinternals também pode ser usado para captura de despejo post-mortem. Para obter mais informações sobre como usar e baixar o ProcDump, consulte ProcDump.
Como o comando .dump WinDbg, o ProcDump pode capturar um despejo da falha de forma não interativa. A captura pode ocorrer em qualquer sessão do sistema Windows.
O ProcDump é encerrado quando a captura do arquivo de despejo é concluída, o WER relata a falha e o processo de falha é encerrado.
Use procdump -i
para instalar o procdump e -u para desinstalar o ProcDump para a depuração post mortem de 32 e 64 bits.
<Path>\procdump.exe -i
Os comandos install e uninstall geram os valores do Registro modificados em caso de êxito e os erros em caso de falha.
As opções de linha de comando ProcDump no Registro são definidas como:
Debugger = <Path>\ProcDump.exe -accepteula -j "<DumpFolder>" %ld %ld %p
O ProcDump usa todos os 3 parâmetros - PID, Event e JIT_DEBUG_INFO. Para obter mais informações sobre o parâmetro JIT_DEBUG_INFO, consulte Depuração JIT (Just In Time) abaixo.
O tamanho do dump capturado é padronizado para Mini (processo/threads/identificadores/módulos/espaço de endereço) sem um conjunto de opções de tamanho, MiniPlus (Mini mais MEM_PRIVATE páginas) com -mp definido ou Full (toda a memória - equivalente a ".dump /mA") com -ma definido.
Para sistemas com espaço em disco suficiente, recomenda-se uma captura completa (-ma).
Use -ma com a opção -i para especificar uma captura de toda a memória. Opcionalmente, forneça um caminho para os arquivos de despejo.
<Path>\procdump.exe -ma -i c:\Dumps
Para sistemas com espaço em disco limitado, recomenda-se uma captura MiniPlus (-mp).
<Path>\procdump.exe -mp -i c:\Dumps
A pasta para salvar o arquivo de despejo é opcional. O padrão é a pasta atual. A pasta deve ser protegida com uma ACL igual ou melhor do que a usada para C:\Windows\Temp. Para obter mais informações sobre como gerenciar a segurança relacionada a pastas, consulte Segurança durante a depuração post-mortem.
Para desinstalar o ProcDump como o depurador post-mortem e restaurar as configurações anteriores, use a opção -u (Desinstalar).
<Path>\procdump.exe -u
Para obter informações adicionais sobre o ProcDump, consulte ProcDump e Windows SysInternals Administrator's Reference por Mark Russinovich e Aaron Margosis publicado pela Microsoft Press.
Depuração JIT (Just In Time)
Definindo o contexto para o aplicativo com falha
Conforme discutido anteriormente, é muito desejável definir o contexto para a exceção que causou a falha usando o parâmetro JIT_DEBUG_INFO. Para obter mais informações sobre isso, consulte .jdinfo (Usar JIT_DEBUG_INFO).
Ferramentas de Depuração para Windows
Este exemplo mostra como editar o Registro para executar um comando inicial (-c) que usa o comando .jdinfo <address> para exibir as informações adicionais da exceção e alterar o contexto para o local da exceção (semelhante a como .ecxr é usado, defina o contexto para o registro de exceção).
Debugger = "<Path>\windbg.exe -p %ld -e %ld -c ".jdinfo 0x%p"
Auto = 1
O parâmetro %p é o endereço de uma estrutura JIT_DEBUG_INFO no espaço de endereço do processo de destino. O parâmetro %p é pré-anexado com 0x para que seja interpretado como um valor hexadecimal. Para obter mais informações, consulte .jdinfo (Usar JIT_DEBUG_INFO).
Para depurar uma combinação de aplicativos de 32 e 64 bits, configure as chaves do Registro de 32 e 64 bits (descritas acima), definindo o caminho adequado para o local dos WinDbg.exe de 64 bits e 32 bits.
Criando um arquivo de despejo usando .dump
Para capturar um arquivo de despejo sempre que ocorrer uma falha que inclua os dados JIT_DEBUG_INFO, use .dump /j <address>.
<Path>\windbg.exe -p %ld -e %ld -c ".dump /j %p /u <DumpPath>\AeDebug.dmp; qd"
Use a opção /u para gerar um nome de arquivo exclusivo para permitir que vários arquivos de despejo sejam criados automaticamente. Para obter mais informações sobre as opções, consulte .dump (Criar arquivo de despejo).
O despejo criado terá os dados JITDEBUG_INFO armazenados como o contexto de exceção padrão. Em vez de usar .jdinfo para exibir as informações de exceção e definir o contexto, use .exr -1 para exibir o registro de exceção e .ecxr para definir o contexto. Para obter mais informações, consulte .exr (Exibir Registro de Exceção) e .ecxr (Exibir Registro de Contexto de Exceção).
Relatório de erros do Windows - q / qd
A maneira como a sessão de depuração termina determina se o Relatório de Erros do Windows relata a falha.
Se a sessão de depuração for desanexada usando qd antes do fechamento do depurador, o WER relatará a falha.
Se a sessão de depuração for encerrada usando q (ou se o depurador for fechado sem desanexar), o WER não relatará a falha.
Anexar ; q ou ; qd ao final da cadeia de caracteres de comando para invocar o comportamento desejado.
Por exemplo, para permitir que o WER relate a falha depois que o CDB capturar um despejo, configure essa cadeia de caracteres de comando.
<Path>\cdb.exe -p %ld -e %ld -c ".dump /j 0x%p /u c:\Dumps\AeDebug.dmp; qd"
Este exemplo permitiria que o WER relatasse a falha depois que o WinDbg capturasse um despejo.
<Path>\windbg.exe -p %ld -e %ld -c ".dump /j %p /u <DumpPath>\AeDebug.dmp; qd""
Vulnerabilidades de segurança
Se você estiver pensando em habilitar a depuração post-mortem em um computador que você compartilha com outras pessoas, consulte Segurança durante a depuração post-mortem.