.jdinfo (JIT_DEBUG_INFO verwenden)
Der Befehl ".jdinfo " verwendet eine JIT_DEBUG_INFO Struktur als Quelle der Ausnahme und des Kontexts für das just in time (JIT)-Debugging. Die Adresse an die Struktur wird mithilfe des im Registrierungseintrag "AeDebug" angegebenen Parameters %p an den JDINFO-Befehl übergeben.
Weitere Informationen zu den verwendeten Registrierungsschlüsseln finden Sie unter Aktivieren des Postmortem-Debuggings. Weitere Informationen zum Registrieren von Kontexten finden Sie unter Ändern von Kontexten.
.jdinfo Address
Parameter
Adresse
Gibt die Adresse der JIT_DEBUG_INFO Struktur an. Die Adresse an die Struktur wird mithilfe des im Registrierungseintrag "AeDebug" angegebenen Parameters %p an den JDINFO-Befehl übergeben.
Environment
Modi |
Benutzermodus |
Targets |
Live, Crash Dump |
Plattformen |
Alle |
Beispiel
In diesem Beispiel wird gezeigt, wie der AeDebug-Registrierungseintrag für die Verwendung von WinDbg als JIT-Debugger konfiguriert werden kann.
Debugger = "Path\WinDbg.EXE -p %ld -e %ld -c ".jdinfo 0x%p"
Wenn ein Absturz auftritt, wird der konfigurierte JIT-Debugger aufgerufen, und der Parameter %p wird verwendet, um die Adresse der JIT_DEBUG_INFO Struktur an den JDINFO-Befehl zu übergeben, der nach dem Starten des Debuggers ausgeführt wird.
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=????????
Hinweise
Der Befehl ".jdinfo " verwendet die in Windows Vista eingeführten AeDebug-Registrierungsinformationen . Weitere Informationen zu den verwendeten Registrierungsschlüsseln finden Sie unter Aktivieren des Postmortem-Debuggings. Der Befehl ".jdinfo " verwendet die Adresse einer JIT_DEBUG_INFO, die das System für AeDebug eingerichtet hat, und legt den Kontext auf die Ausnahme fest, die den Absturz verursacht hat.
Sie können den Befehl ".jdinfo " anstelle von "-g " in AeDebug verwenden, um den Debugger ohne Ausführung auf den AeDebug-Zustand festzulegen.
Dieser Zustand kann vorteilhaft sein, da unter üblichen Bedingungen, wenn eine Ausnahme im Benutzermodus auftritt, die folgende Sequenz auftritt:
Das Microsoft Windows-Betriebssystem hält die Ausführung der Anwendung an.
Der Postmortemdebugger wird gestartet.
Der Debugger wird an die Anwendung angefügt.
Der Debugger gibt einen "Go"-Befehl aus. (Dieser Befehl wird durch die TASTE "-g " im Schlüssel "AeDebug " verursacht.)
Das Ziel versucht, die Ausführung auszuführen, und kann auf dieselbe Ausnahme stoßen oder nicht.
Diese Ausnahme bricht in den Debugger auf.
Es gibt mehrere Probleme, die aufgrund dieser Ereignisse auftreten können:
Ausnahmen werden nicht immer wiederholt, möglicherweise aufgrund einer vorübergehenden Bedingung, die nicht mehr vorhanden ist, wenn die Ausnahme neu gestartet wird.
Ein anderes Ereignis, z. B. eine andere Ausnahme, kann auftreten. Es gibt keine Möglichkeit zu wissen, ob es mit dem ursprünglichen Ereignis identisch ist.
Beim Anfügen eines Debuggers wird ein neuer Thread eingefügt, der blockiert werden kann, wenn ein Thread die Ladesperre hält. Das Einfügen eines neuen Threads kann eine erhebliche Störung des Prozesses sein.
Wenn Sie -c .jdinfo anstelle von -g in Ihrem AeDebug-Schlüssel verwenden, tritt keine Ausführung auf. Stattdessen werden die Ausnahmeinformationen aus der JIT_DEBUG_INFO Struktur mithilfe der Variablen %p abgerufen.
Betrachten Sie beispielsweise den folgenden AeDebug-Schlüssel .
ntsd -p %ld -e %ld -c ".jdinfo 0x%p"
Das folgende Beispiel ist noch weniger invasive. Der Pv-Schalter bewirkt, dass der Debugger nicht invasiv anfügt, wodurch keine neuen Threads in das Ziel eingefügt werden.
ntsd -pv -p %ld -e %ld -c ".jdinfo 0x%p"
Wenn Sie diese option verwenden, die nicht invasiv ist, beendet der Debugger den Prozess nicht. Sie können den Prozess mit dem Befehl KILL (Kill Process) beenden.
Wenn Sie dies zum Debuggen von Dumpdateien verwenden möchten, sollten Sie ".dump /j" verwenden, um die JIT_DEBUG_INFO Struktur zu Ihrer Dumpdatei hinzuzufügen, wenn die Dumpdatei erstellt wird.
Die JIT_DEBUG_INFO Struktur wird wie folgt definiert.
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;
Sie können den Befehl dt verwenden, um die JIT_DEBUG_INFO Struktur anzuzeigen.
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
Anzeigen des Ausnahmedatensatzes, des Aufrufstapels und des LastEvent mithilfe von WinDbg
Nachdem der JDINFO-Befehl verwendet wurde, um den Kontext auf den Moment des Fehlers festzulegen, können Sie den ausnahmedatensatz anzeigen, der von JDINFO, dem Aufrufstapel und dem letzten Ereignis zurückgegeben wird, wie unten dargestellt, um die Ursache zu untersuchen.
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)