.jdinfo(JIT_DEBUG_INFO 사용)
.jdinfo 명령은 JIT(Just-In-Time) 디버깅에 대한 예외 및 컨텍스트의 원본으로 JIT_DEBUG_INFO 구조를 사용합니다. 구조체에 대한 주소는 AeDebug 레지스트리 항목에 지정된 %p 매개 변수를 사용하여 .jdinfo 명령에 전달됩니다.
사용되는 레지스트리 키에 대한 자세한 내용은 Postmortem 디버깅 사용을 참조하세요. 레지스터 컨텍스트에 대한 자세한 내용은 컨텍스트 변경을 참조하세요.
.jdinfo Address
매개 변수
주소
JIT_DEBUG_INFO 구조체의 주소를 지정합니다. 구조체에 대한 주소는 AeDebug 레지스트리 항목에 지정된 %p 매개 변수를 사용하여 .jdinfo 명령에 전달됩니다.
Environment
모드 |
사용자 모드 |
대상 |
라이브, 크래시 덤프 |
플랫폼 |
모두 |
예제
이 예제에서는 WinDbg를 사용하도록 AeDebug 레지스트리 항목을 구성하는 방법을 JIT 디버거로 사용할 수 있습니다.
Debugger = "Path\WinDbg.EXE -p %ld -e %ld -c ".jdinfo 0x%p"
그런 다음 크래시가 발생하면 구성된 JIT 디버거가 호출되고 %p 매개 변수를 사용하여 디버거가 시작된 후 실행되는 .jdinfo 명령에 JIT_DEBUG_INFO 구조체의 주소를 전달합니다.
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 레지스트리 정보를 사용합니다. 사용되는 레지스트리 키에 대한 자세한 내용은 Postmortem 디버깅 사용을 참조하세요. .jdinfo 명령은 시스템이 AeDebug에 대해 설정한 JIT_DEBUG_INFO 주소를 사용하고 컨텍스트를 크래시가 발생한 예외로 설정합니다.
AeDebug에서 -g 대신 .jdinfo 명령을 사용하여 실행 없이 디버거를 AeDebug 상태로 설정할 수 있습니다.
일반적인 조건에서 사용자 모드 예외가 발생할 때 다음 시퀀스가 발생하기 때문에 이 상태가 유리할 수 있습니다.
Microsoft Windows 운영 체제는 애플리케이션 실행을 중지합니다.
사후 관리 디버거가 시작됩니다.
디버거는 애플리케이션에 연결됩니다.
디버거는 "Go" 명령을 실행합니다. (이 명령은 AeDebug 키의 -g에 의해 발생합니다.)
대상은 실행을 시도하며 동일한 예외가 발생할 수도 있고 그렇지 않을 수도 있습니다.
이 예외는 디버거에 침입합니다.
이러한 이벤트로 인해 발생할 수 있는 몇 가지 문제가 있습니다.
예외가 다시 시작될 때 더 이상 존재하지 않는 일시적인 조건으로 인해 예외가 항상 반복되는 것은 아닙니다.
다른 예외와 같은 다른 이벤트가 발생할 수 있습니다. 원래 이벤트와 동일한지 여부를 알 수 있는 방법은 없습니다.
디버거를 연결하려면 새 스레드를 삽입해야 하며, 스레드가 로더 잠금을 유지하는 경우 차단할 수 있습니다. 새 스레드를 삽입하는 것은 프로세스의 상당한 방해가 될 수 있습니다.
AeDebug 키에서 -g 대신 -c .jdinfo를 사용하는 경우 실행이 발생하지 않습니다. 대신 예외 정보는 %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(프로세스 종료) 명령을 사용하여 프로세스를 종료할 수 있습니다.
덤프 파일 디버깅에 이 값을 사용하려면 덤프 파일을 만들 때 .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)
피드백
https://aka.ms/ContentUserFeedback
출시 예정: 2024년 내내 콘텐츠에 대한 피드백 메커니즘으로 GitHub 문제를 단계적으로 폐지하고 이를 새로운 피드백 시스템으로 바꿀 예정입니다. 자세한 내용은 다음을 참조하세요.다음에 대한 사용자 의견 제출 및 보기