Condividi tramite


.jdinfo (usare JIT_DEBUG_INFO)

Il comando .jdinfo usa una struttura JIT_DEBUG_INFO come origine dell'eccezione e del contesto per il debug JIT (Just-In-Time). L'indirizzo della struttura viene passato al comando .jdinfo usando il parametro %p specificato nella voce del Registro di sistema AeDebug.

Per altre informazioni sulle chiavi del Registro di sistema usate, vedere Abilitazione del debug postmortem. Per altre informazioni sui contesti di registrazione, vedere Changing Contexts.For more information about register contexts, see Changing Contexts.

.jdinfo Address 

Parametri

Indirizzo
Specifica l'indirizzo della struttura JIT_DEBUG_INFO. L'indirizzo della struttura viene passato al comando .jdinfo usando il parametro %p specificato nella voce del Registro di sistema AeDebug.

Ambiente

Modalità

Modalità utente

Destinazioni

Live, crash dump

Piattaforme

Tutte le date

Esempio

In questo esempio viene illustrato come configurare la voce del Registro di sistema AeDebug per l'uso di WinDbg come debugger JIT.

Debugger = "Path\WinDbg.EXE -p %ld -e %ld -c ".jdinfo 0x%p"

Quindi, quando si verifica un arresto anomalo, viene richiamato il debugger JIT configurato e il parametro %p viene usato per passare l'indirizzo della struttura JIT_DEBUG_INFO al comando .jdinfo eseguito dopo l'avvio del debugger.

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=????????

Osservazioni:

Il comando .jdinfo usa le informazioni del Registro di sistema di AeDebug introdotte in Windows Vista. Per altre informazioni sulle chiavi del Registro di sistema usate, vedere Abilitazione del debug postmortem. Il comando .jdinfo accetta l'indirizzo di un JIT_DEBUG_INFO impostato dal sistema per AeDebug e imposta il contesto sull'eccezione che ha causato l'arresto anomalo.

È possibile usare il comando .jdinfo anziché -g in AeDebug per impostare il debugger sullo stato AeDebug senza richiedere l'esecuzione.

Questo stato può essere vantaggioso, perché in condizioni normali, quando si verifica un'eccezione in modalità utente, si verifica la sequenza seguente:

  1. Il sistema operativo Microsoft Windows interrompe l'esecuzione dell'applicazione.

  2. Viene avviato il debugger postmortem.

  3. Il debugger si connette all'applicazione.

  4. Il debugger genera un comando "Go". Questo comando è causato da -g nella chiave AeDebug .

  5. La destinazione tenta di eseguire e può o non riscontrare la stessa eccezione.

  6. Questa eccezione si interrompe nel debugger.

Esistono diversi problemi che possono verificarsi a causa di questi eventi:

  • Le eccezioni non vengono sempre ripetute, probabilmente a causa di una condizione temporanea che non esiste più quando l'eccezione viene riavviata.

  • Potrebbe verificarsi un altro evento, ad esempio un'eccezione diversa. Non c'è modo di sapere se è identico all'evento originale.

  • Il collegamento di un debugger comporta l'inserimento di un nuovo thread, che può essere bloccato se un thread contiene il blocco del caricatore. L'inserimento di un nuovo thread può essere un disturbo significativo del processo.

Se si usa -c .jdinfo anziché -g nella chiave AeDebug , non viene eseguita alcuna esecuzione. Al contrario, le informazioni sull'eccezione vengono recuperate dalla struttura JIT_DEBUG_INFO usando la variabile %p.

Si consideri ad esempio la seguente chiave AeDebug .

ntsd -p %ld -e %ld -c ".jdinfo 0x%p"

L'esempio seguente è ancora meno invasivo. L'opzione -pv fa sì che il debugger si allega in modo non invasivo, che non inserisce nuovi thread nella destinazione.

ntsd -pv -p %ld -e %ld -c ".jdinfo 0x%p"

Se si usa questa opzione non invasiva, l'uscita dal debugger non termina il processo. È possibile usare il comando .kill (Kill Process) per terminare il processo.

Se si vuole usarlo per il debug di file di dump, è consigliabile usare .dump /j per aggiungere la struttura JIT_DEBUG_INFO al file di dump, quando viene creato il file dump.

La struttura JIT_DEBUG_INFO è definita come segue.

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;

È possibile usare il comando dt per visualizzare la struttura 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

Visualizzazione del record di eccezione, dello stack di chiamate e dell'ultimo evento tramite WinDbg

Dopo aver usato il comando .jdinfo per impostare il contesto sul momento dell'errore, è possibile visualizzare il record di eccezione restituito da .jdinfo, lo stack di chiamate e l'ultimo evento, come illustrato di seguito, per analizzare la 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)