Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Perintah .jdinfo menggunakan struktur JIT_DEBUG_INFO sebagai sumber pengecualian dan konteks untuk penelusuran kesalahan just in time (JIT). Alamat ke struktur diteruskan ke perintah .jdinfo menggunakan parameter %p yang ditentukan dalam entri registri AeDebug.
Untuk informasi selengkapnya tentang kunci registri yang digunakan, lihat Mengaktifkan Debugging Postmortem. Untuk informasi selengkapnya tentang konteks pendaftaran, lihat Mengubah Konteks.
.jdinfo Address
Parameter
Alamat
Menentukan alamat struktur JIT_DEBUG_INFO. Alamat ke struktur diteruskan ke perintah .jdinfo menggunakan parameter %p yang ditentukan dalam entri registri AeDebug.
Lingkungan
Mode |
Mode pengguna |
Target |
Live, crash dump |
Platform |
Semua |
Contoh
Contoh ini menunjukkan bagaimana entri registri AeDebug dapat dikonfigurasi untuk menggunakan WinDbg dapat digunakan sebagai debugger JIT.
Debugger = "Path\WinDbg.EXE -p %ld -e %ld -c ".jdinfo 0x%p"
Kemudian, ketika crash terjadi, debugger JIT yang dikonfigurasi dipanggil dan parameter %p digunakan untuk meneruskan alamat struktur JIT_DEBUG_INFO ke perintah .jdinfo yang dijalankan setelah debugger dimulai.
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=????????
Keterangan
Perintah .jdinfo menggunakan informasi registri AeDebug yang diperkenalkan di Windows Vista. Untuk informasi selengkapnya tentang kunci registri yang digunakan, lihat Mengaktifkan Debugging Postmortem. Perintah .jdinfo mengambil alamat JIT_DEBUG_INFO yang disiapkan sistem untuk AeDebug dan mengatur konteks ke pengecualian yang menyebabkan crash.
Anda dapat menggunakan perintah .jdinfo alih-alih -g di AeDebug agar debugger Anda diatur ke status AeDebug tanpa memerlukan eksekusi.
Status ini bisa menguntungkan, karena dalam kondisi biasa, ketika pengecualian mode pengguna terjadi, urutan berikut terjadi:
Sistem operasi Microsoft Windows menghentikan eksekusi aplikasi.
Debugger postmortem dimulai.
Debugger melampirkan ke aplikasi.
Debugger mengeluarkan perintah "Go". (Perintah ini disebabkan oleh -g dalam kunci AeDebug .)
Target mencoba untuk mengeksekusi dan mungkin atau mungkin tidak mengalami pengecualian yang sama.
Pengecualian ini masuk ke debugger.
Ada beberapa masalah yang dapat terjadi karena peristiwa ini:
Pengecualian tidak selalu berulang, mungkin karena kondisi sementara yang tidak lagi ada ketika pengecualian dimulai ulang.
Peristiwa lain, seperti pengecualian yang berbeda, mungkin terjadi. Tidak ada cara untuk mengetahui apakah itu identik dengan peristiwa asli.
Melampirkan debugger melibatkan injeksi utas baru, yang dapat diblokir jika utas menahan kunci loader. Menyuntikkan utas baru dapat menjadi gangguan proses yang signifikan.
Jika Anda menggunakan -c .jdinfo alih-alih -g di kunci AeDebug Anda, tidak ada eksekusi yang terjadi. Sebagai gantinya, informasi pengecualian diambil dari struktur JIT_DEBUG_INFO menggunakan variabel %p.
Misalnya, pertimbangkan kunci AeDebug berikut.
ntsd -p %ld -e %ld -c ".jdinfo 0x%p"
Contoh berikut bahkan kurang invasif. Sakelar -pv menyebabkan debugger terpasang secara noninvasif, yang tidak menyuntikkan utas baru apa pun ke target.
ntsd -pv -p %ld -e %ld -c ".jdinfo 0x%p"
Jika Anda menggunakan opsi noninvasif ini, keluar dari debugger tidak mengakhiri proses. Anda dapat menggunakan perintah .kill (Kill Process) untuk mengakhiri proses.
Jika Anda ingin menggunakan ini untuk penelusuran kesalahan file cadangan, Anda harus menggunakan .dump /j untuk menambahkan struktur JIT_DEBUG_INFO ke file cadangan Anda, saat file cadangan dibuat.
Struktur JIT_DEBUG_INFO didefinisikan sebagai berikut.
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;
Anda dapat menggunakan perintah dt untuk menampilkan struktur 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
Menampilkan Rekaman Pengecualian, Tumpukan Panggilan dan LastEvent Menggunakan WinDbg
Setelah perintah .jdinfo digunakan untuk mengatur konteks ke saat kegagalan, Anda dapat melihat rekaman pengecualian yang dikembalikan oleh .jdinfo, tumpukan panggilan dan lastevent, seperti yang ditunjukkan di bawah ini, untuk menyelidiki penyebabnya.
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)