.jdinfo (Use JIT_DEBUG_INFO)
O comando .jdinfo usa uma estrutura JIT_DEBUG_INFO como a origem da exceção e o contexto para a depuração JIT (just in time). O endereço para a estrutura é passado para o comando .jdinfo usando o parâmetro %p especificado na entrada do Registro AeDebug.
Para obter mais informações sobre as chaves do Registro usadas, consulte Habilitando a depuração post-mortem. Para obter mais informações sobre contextos de registro, consulte Alterando contextos.
.jdinfo Address
Parâmetros
Endereço
Especifica o endereço da estrutura JIT_DEBUG_INFO. O endereço para a estrutura é passado para o comando .jdinfo usando o parâmetro %p especificado na entrada do Registro AeDebug.
Ambiente
Modos |
Modo de usuário |
Destinos |
Ao vivo, despejo de memória |
Plataformas |
Tudo |
Exemplo
Este exemplo mostra como a entrada do Registro AeDebug pode ser configurada para usar o WinDbg pode ser usado como o depurador JIT.
Debugger = "Path\WinDbg.EXE -p %ld -e %ld -c ".jdinfo 0x%p"
Em seguida, quando ocorre uma falha, o depurador JIT configurado é invocado e o parâmetro %p é usado para passar o endereço da estrutura JIT_DEBUG_INFO para o comando .jdinfo que é executado após o início do depurador.
nMicrosoft (R) Windows Debugger Version 10.0.10240.9 AMD64
Copyright (c) Microsoft Corporation. All rights reserved.
*** wait with pending attach
Executable search path is:
...
ModLoad: 00000000`68a20000 00000000`68ac3000 C:\WINDOWS\WinSxS\amd64_microsoft.vc90.crt_1fc8b3b9a1e18e3b_9.0.30729.9247_none_08e394a1a83e212f\MSVCR90.dll
(153c.5d0): Break instruction exception - code 80000003 (first chance)
Processing initial command '.jdinfo 0x00000000003E0000'
ntdll!DbgBreakPoint:
00007ffc`81a986a0 cc int 3
0:003> .jdinfo 0x00000000003E0000
----- Exception occurred on thread 0:15c8
ntdll!ZwWaitForMultipleObjects+0x14:
00007ffc`81a959a4 c3 ret
----- Exception record at 00000000`003e0028:
ExceptionAddress: 00007ff791d81014 (CrashAV_x64!wmain+0x0000000000000014)
ExceptionCode: c0000005 (Access violation)
ExceptionFlags: 00000000
NumberParameters: 2
Parameter[0]: 0000000000000001
Parameter[1]: 0000000000000000
Attempt to write to address 0000000000000000
----- Context record at 00000000`003e00c0:
rax=0000000000000000 rbx=0000000000000000 rcx=00007ffc81a954d4
rdx=0000000000000000 rsi=0000000000000000 rdi=0000000000000001
rip=00007ff791d81014 rsp=00000000006ff8b0 rbp=0000000000000000
r8=00000000006ff808 r9=0000000000000000 r10=0000000000000000
r11=0000000000000000 r12=0000000000000000 r13=0000000000000000
r14=0000000000000000 r15=0000000000000000
iopl=0 nv up ei pl zr na po nc
cs=0033 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00010246
CrashAV_x64!wmain+0x14:
00007ff7`91d81014 45891b mov dword ptr [r11],r11d ds:00000000`00000000=????????
Comentários
O comando .jdinfo usa as informações do Registro AeDebug introduzidas no Windows Vista. Para obter mais informações sobre as chaves do Registro usadas, consulte Habilitando a depuração post-mortem. O comando .jdinfo usa o endereço de um JIT_DEBUG_INFO que o sistema configurou para o AeDebug e define o contexto para a exceção que causou a falha.
Você pode usar o comando .jdinfo em vez de -g no AeDebug para que o depurador seja definido como o estado AeDebug sem exigir execução.
Esse estado pode ser vantajoso, pois em condições normais, quando ocorre uma exceção no modo de usuário, ocorre a seguinte sequência:
O sistema operacional Microsoft Windows interrompe a execução do aplicativo.
O depurador post-mortem é iniciado.
O depurador é anexado ao aplicativo.
O depurador emite um comando "Go". (Esse comando é causado pelo -g na chave AeDebug .)
O destino tenta executar e pode ou não encontrar a mesma exceção.
Essa exceção é interrompida no depurador.
Existem vários problemas que podem ocorrer devido a esses eventos:
As exceções nem sempre se repetem, possivelmente devido a uma condição transitória que não existe mais quando a exceção é reiniciada.
Outro evento, como uma exceção diferente, pode ocorrer. Não há como saber se é idêntico ao evento original.
Anexar um depurador envolve a injeção de um novo thread, que pode ser bloqueado se um thread estiver mantendo o bloqueio do carregador. Injetar um novo thread pode ser uma perturbação significativa do processo.
Se você usar -c .jdinfo em vez de -g em sua chave AeDebug , nenhuma execução ocorrerá. Em vez disso, as informações de exceção são recuperadas da estrutura JIT_DEBUG_INFO usando a variável %p.
Por exemplo, considere a seguinte chave AeDebug .
ntsd -p %ld -e %ld -c ".jdinfo 0x%p"
O exemplo a seguir é ainda menos invasivo. A opção -pv faz com que o depurador seja anexado de forma não invasiva, o que não injeta novos threads no destino.
ntsd -pv -p %ld -e %ld -c ".jdinfo 0x%p"
Se você usar essa opção não invasiva, sair do depurador não encerrará o processo. Você pode usar o comando .kill (Kill Process) para encerrar o processo.
Se você quiser usar isso para depuração de arquivo de despejo, use .dump /j para adicionar a estrutura JIT_DEBUG_INFO ao arquivo de despejo, quando o arquivo de despejo for criado.
A estrutura JIT_DEBUG_INFO é definida da seguinte forma.
typedef struct _JIT_DEBUG_INFO {
DWORD dwSize;
DWORD dwProcessorArchitecture;
DWORD dwThreadID;
DWORD dwReserved0;
ULONG64 lpExceptionAddress;
ULONG64 lpExceptionRecord;
ULONG64 lpContextRecord;
} JIT_DEBUG_INFO, *LPJIT_DEBUG_INFO;
Você pode usar o comando dt para exibir a estrutura JIT_DEBUG_INFO.
0: kd> dt JIT_DEBUG_INFO
nt!JIT_DEBUG_INFO
+0x000 dwSize : Uint4B
+0x004 dwProcessorArchitecture : Uint4B
+0x008 dwThreadID : Uint4B
+0x00c dwReserved0 : Uint4B
+0x010 lpExceptionAddress : Uint8B
+0x018 lpExceptionRecord : Uint8B
+0x020 lpContextRecord : Uint8B
Exibindo o registro de exceção, a pilha de chamadas e o LastEvent usando o WinDbg
Depois que o comando .jdinfo tiver sido usado para definir o contexto para o momento da falha, você poderá exibir o registro de exceção retornado por .jdinfo, a pilha de chamadas e o lastevent, conforme mostrado abaixo, para investigar a causa.
0:000> .jdinfo 0x00000000003E0000
----- Exception occurred on thread 0:15c8
ntdll!NtWaitForMultipleObjects+0x14:
00007ffc`81a959a4 c3 ret
----- Exception record at 00000000`003e0028:
ExceptionAddress: 00007ff791d81014 (CrashAV_x64!wmain+0x0000000000000014)
ExceptionCode: c0000005 (Access violation)
ExceptionFlags: 00000000
NumberParameters: 2
Parameter[0]: 0000000000000001
Parameter[1]: 0000000000000000
Attempt to write to address 0000000000000000
...
0:000> k
*** Stack trace for last set context - .thread/.cxr resets it
# Child-SP RetAddr Call Site
00 00000000`006ff8b0 00007ff7`91d811d2 CrashAV_x64!wmain+0x14 [c:\my\my_projects\crash\crashav\crashav.cpp @ 14]
01 00000000`006ff8e0 00007ffc`7fa38364 CrashAV_x64!__tmainCRTStartup+0x11a [f:\dd\vctools\crt_bld\self_64_amd64\crt\src\crtexe.c @ 579]
02 00000000`006ff910 00007ffc`81a55e91 KERNEL32!BaseThreadInitThunk+0x14
03 00000000`006ff940 00000000`00000000 ntdll!RtlUserThreadStart+0x21
0:000> .lastevent
Last event: 153c.5d0: Break instruction exception - code 80000003 (first chance)
debugger time: Thu Sep 8 12:55:08.968 2016 (UTC - 7:00)