.jdinfo(使用 JIT_DEBUG_INFO)
.jdinfo 命令使用JIT_DEBUG_INFO结构作为异常和上下文的源,以便进行实时 (JIT) 调试。 使用 AeDebug 注册表项中指定的 %p 参数将结构地址传递给 .jdinfo 命令。
有关使用的注册表项的详细信息,请参阅 “启用事后调试”。 有关注册上下文的详细信息,请参阅 更改上下文。
.jdinfo Address
参数
地址
指定JIT_DEBUG_INFO结构的地址。 使用 AeDebug 注册表项中指定的 %p 参数将结构地址传递给 .jdinfo 命令。
环境
模式 |
用户模式 |
目标 |
实时、崩溃转储 |
平台 |
全部 |
示例
此示例演示如何将 AeDebug 注册表项配置为使用 WinDbg 可用作 JIT 调试器。
Debugger = "Path\WinDbg.EXE -p %ld -e %ld -c ".jdinfo 0x%p"
然后,发生崩溃时,将调用配置的 JIT 调试器,并使用 %p 参数将JIT_DEBUG_INFO结构的地址传递给 启动调试器后执行的 .jdinfo 命令。
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=????????
注解
.jdinfo 命令使用 Windows Vista 中引入的 AeDebug 注册表信息。 有关使用的注册表项的详细信息,请参阅 “启用事后调试”。 .jdinfo 命令采用系统为 AeDebug 设置的JIT_DEBUG_INFO的地址,并将上下文设置为导致崩溃的异常。
可以使用 .jdinfo 命令而不是 AeDebug 中的 -g 将调试器设置为 AeDebug 状态,而无需执行。
此状态可能比较有利,因为在通常情况下,发生用户模式异常时,会发生以下序列:
Microsoft Windows 操作系统停止执行应用程序。
启动事后调试器。
调试器附加到应用程序。
调试器发出“Go”命令。 (此命令是由 AeDebug 键中的 -g 引起的。
目标尝试执行并可能遇到相同的异常。
此异常中断到调试器中。
由于这些事件,可能会出现以下几个问题:
异常并不总是重复的,可能是由于重启异常时不再存在的暂时性条件。
可能会发生另一个事件,例如不同的异常。 无法知道它是否与原始事件相同。
附加调试器涉及注入新线程,如果线程持有加载程序锁,则可以阻止该线程。 注入新线程可能是进程的严重干扰。
如果在 AeDebug 键中使用 -c .jdinfo 而不是 -g,则不会执行。 而是使用 %p 变量从JIT_DEBUG_INFO结构检索异常信息。
例如,请考虑以下 AeDebug 键。
ntsd -p %ld -e %ld -c ".jdinfo 0x%p"
以下示例的侵入性更低。 -pv 开关会导致调试器以非侵入方式附加,这不会向目标注入任何新线程。
ntsd -pv -p %ld -e %ld -c ".jdinfo 0x%p"
如果使用此非侵入性选项,退出调试器不会结束该过程。 可以使用 .kill (Kill Process) 命令结束进程。
如果要将此用于转储文件调试,则应使用 .dump /j 在创建转储文件时将JIT_DEBUG_INFO结构添加到转储文件。
JIT_DEBUG_INFO结构定义如下。
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;
可以使用 dt 命令显示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
使用 WinDbg 查看异常记录、调用堆栈和 LastEvent
使用 .jdinfo 命令将上下文设置为失败时刻后,可以查看 .jdinfo、调用堆栈和 lastevent 返回的异常记录,如下所示,以调查原因。
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)