.jdinfo (JIT_DEBUG_INFO の使用)

.jdinfo コマンドは、JIT_DEBUG_INFO 構造体を例外のソースおよびジャスト イン タイム (JIT) デバッグのコンテキストとして使用します。 構造体のアドレスは、AeDebug レジストリ エントリで指定された %p パラメータを使用して .jdinfo コマンドに渡されます。

使用されるレジストリ キーの詳細については、次を参照してください 事後分析デバッグを有効にする. レジスタ コンテキストの詳細については、 「コンテキストの変更」を参照してください

.jdinfo Address 

パラメーター

Address
JIT_DEBUG_INFO 構造体のアドレスを指定します。 構造体のアドレスは、AeDebug レジストリ エントリで指定された %p パラメータを使用して .jdinfo コマンドに渡されます。

Environment

モード

ユーザー モード

Targets

ライブ、クラッシュ ダンプ

プラットフォーム

すべて

この例は、WinDbg を JIT デバッガーとして使用できるように AeDebug レジストリ エントリを構成する方法を示しています。

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 を使用しますコマンド AeDebug Windows Vistaで導入されたレジストリ情報です。 使用されるレジストリ キーの詳細については、次を参照してください 事後分析デバッグを有効にする. その .jdinfo コマンドは、システムがセットアップした JIT_DEBUG_INFO のアドレスを取得します AeDebug そしてクラッシュの原因となった例外にコンテキストを設定します。

を使用できます .jdinfo コマンドの代わりに -g in AeDebug デバッガーを次のように設定するには、 AeDebug 実行を必要としない状態。

通常の状況では、ユーザー モード例外が発生すると次のシーケンスが発生するため、この状態は有利な場合があります。

  1. Microsoft Windows オペレーティング システムはアプリケーションの実行を停止します。

  2. 事後デバッガーが開始されます。

  3. デバッガーはアプリケーションに接続されます。

  4. デバッガは「Go」コマンドを発行します。 (このコマンドの原因は、 -gAeDebug キー.)

  5. ターゲットは実行を試みますが、同じ例外が発生する場合と発生しない場合があります。

  6. この例外によりデバッガが中断されます。

これらのイベントが原因で、いくつかの問題が発生する可能性があります。

  • 例外が常に繰り返されるわけではありません。これは、一時的な状態が例外の再開時に存在しなくなることが原因である可能性があります。

  • 別の例外などの別のイベントが発生する可能性があります。 それが元のイベントと同一かどうかを知る方法はありません。

  • デバッガーの接続には新しいスレッドの挿入が含まれますが、スレッドがローダー ロックを保持している場合はブロックされる可能性があります。 新しいスレッドを挿入すると、プロセスに重大な障害が発生する可能性があります。

使用する場合は、 -c .jdinfo の代わりに -g in your AeDebug キー、実行は発生しません。 代わりに、例外情報は、%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 によって返された例外レコード、コール スタック、および最後のイベントを表示して、原因を調査できます。

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)