事後デバッグを有効にする

ユーザー モード例外処理

例外とブレークポイント

最も一般的なアプリケーション エラーは例外と呼ばれます。 これには、アクセス違反、0 除算エラー、数値オーバーフロー、CLR 例外、その他多くの種類のエラーが含まれます。 アプリケーションでは、ブレークポイントの割り込みも発生する可能性があります。 これらは、Windows がアプリケーションを実行できない場合 (たとえば、必要なモジュールを読み込めない場合)、またはブレークポイントが発生した場合に発生します。 ブレークポイントは、デバッガーによってコードに挿入することも、 DebugBreak などの関数を介して呼び出すこともできます。

例外ハンドラーの優先順位

構成値とアクティブなデバッガーに基づいて、Windows はさまざまな方法でユーザー モード エラーを処理します。 次のシーケンスは、ユーザー モードのエラー処理に使用される優先順位を示しています。

  1. ユーザー モード デバッガーが現在障害プロセスにアタッチされている場合、すべてのエラーによってターゲットがこのデバッガーに分割されます。

    ユーザー モード デバッガーがアタッチされている限り、 gn (Go With Exception Not Handled) コマンドが使用されている場合でも、他のエラー処理メソッドは使用されません。

  2. ユーザー モード デバッガーがアタッチされておらず、実行中のコードに独自の例外処理ルーチンがある場合 ( 例: try - except)、この例外処理ルーチンはエラーの処理を試みます。

  3. ユーザー モード デバッガーがアタッチされておらず、Windows にオープン カーネル デバッグ接続があり、エラーがブレークポイント割り込みである場合、Windows はカーネル デバッガーへの接続を試みます。

    カーネル デバッグ接続は、Windows のブート プロセス中に開く必要があります。 ユーザー モード割り込みがカーネル デバッガーに割り込まれるのを防ぐ場合は、 -du パラメーターで KDbgCtrl ユーティリティを使用できます。 カーネル デバッグ接続を構成する方法と KDbgCtrl の使用方法の詳細については、「 デバッグのセットアップ」を参照してください。

    カーネル デバッガーでは、 gh (Go With Exception Handled) を使用してエラーを無視し、ターゲットの実行を続行できます。 gn (Go With Exception Not Handled) を使用してカーネル デバッガーをバイパスし、手順 4 に進むことができます。

  4. 手順 1、2、3 の条件が適用されない場合、Windows は AeDebug レジストリ値で構成されたデバッグ ツールをアクティブにします。 この状況で使用するツールとして、任意のプログラムを事前に選択できます。 選択したプログラムは、 事後デバッガーと呼ばれます。

  5. 手順 1、2、3 の条件が適用されず、事後デバッガーが登録されていない場合、Windows エラー報告 (WER) はメッセージを表示し、使用可能な場合はソリューションを提供します。 レジストリに適切な値が設定されている場合、WER はメモリ ダンプ ファイルも書き込みます。 詳細については、「 WER の使用 」および 「User-Mode ダンプの収集」を参照してください。

DebugBreak 関数

事後デバッガーがインストールされている場合は、 DebugBreak 関数を呼び出すことで、ユーザー モード アプリケーションから意図的にデバッガーに分割できます。

事後デバッガーの指定

このセクションでは、WinDbg などのツールを事後デバッガーとして構成する方法について説明します。 構成が完了すると、アプリケーションがクラッシュするたびに事後デバッガーが自動的に開始されます。

事後デバッガー レジストリ キー

Windows エラー報告 (WER) は、AeDebug レジストリ キーに設定された値を使用して事後デバッガー プロセスを作成します。

Hklm\ソフトウェア\マイクロソフト\\ Windows NT CurrentVersion\AeDebug

デバッガー自動の 2 つの主要なレジストリ値があります。デバッガー レジストリ値は、事後デバッガーのコマンド ラインを指定します。 自動レジストリ値は、事後デバッガーが自動的に開始されるか、確認メッセージ ボックスが最初に表示されるかを指定します。

デバッガー (REG_SZ)

このREG_SZ値は、事後デバッグを処理するデバッガーを指定します。

デバッガーが既定のパスにあるディレクトリに配置されていない限り、デバッガーへの完全なパスを一覧表示する必要があります。

コマンド ラインは、3 つのパラメーターを含む printf スタイルの呼び出しを介してデバッガー文字列から生成されます。 順序は固定されていますが、使用可能なパラメーターの一部またはすべてを使用する必要はありません。

DWORD (%ld) - ターゲット プロセスのプロセス ID。

DWORD (%ld) - 事後デバッガー プロセスに複製されたイベント ハンドル。 事後デバッガーによってイベントが通知された場合、WER は事後デバッガーが終了するのを待たずにターゲット プロセスを続行します。 このイベントは、問題が解決された場合にのみ通知する必要があります。 イベントを通知せずに事後デバッガーが終了した場合、WER はターゲット プロセスに関する情報の収集を続行します。

void* (%p) - ターゲット プロセスのアドレス空間に割り当てられたJIT_DEBUG_INFO構造体のアドレス。 構造体には、追加の例外情報とコンテキストが含まれています。

自動 (REG_SZ) このREG_SZ値は常に 0 または 1 です

Auto0 に設定すると、事後デバッグ プロセスが開始される前に確認メッセージ ボックスが表示されます。

Auto1 に設定すると、事後デバッガーがすぐに作成されます。

レジストリを手動で編集する場合は、レジストリの不適切な変更によって Windows の起動が許可されない可能性があるため、非常に慎重に行ってください。

コマンド ラインの使用例

多くの事後デバッガーでは、-p スイッチと -e スイッチを含むコマンド ラインを使用して、パラメーターが PID とイベント (それぞれ) であることを示します。 たとえば、WinDbg をインストールすると windbg.exe -I 、次の値が作成されます。

Debugger = "<Path>\WinDbg -p %ld -e %ld -g"
Auto = 1

WER %ld %ld %p パラメーターを使用する方法には柔軟性があります。 次に例を示します。 WER パラメーターの前後または間のスイッチを指定する必要はありません。 たとえば、 Windows Sysinternals ProcDump を使用して procdump.exe -i インストールすると、WER %ld %ld %p パラメーター間の切り替えなしで次の値が作成されます。

Debugger = "<Path>\procdump.exe" -accepteula -j "c:\Dumps" %ld %ld %p
Auto = 1

32 ビットおよび 64 ビット デバッガー

64 ビット プラットフォームでは、デバッガー (REG_SZ) レジストリ値と自動 (REG_SZ) レジストリ値は、64 ビットおよび 32 ビット アプリケーションに対して個別に定義されます。 Windows 上の追加の Windows (WOW) キーを使用して、32 ビット アプリケーションの事後デバッグ値を格納します。

Hklm\ソフトウェア\Wow6432Node\マイクロソフト\\ Windows NT CurrentVersion\AeDebug

64 ビット プラットフォームでは、32 ビット プロセス用の 32 ビット事後デバッガーと、64 ビット プロセス用の 64 ビット デバッガーを使用します。 これにより、32 ビット プロセスでは、32 ビット スレッドではなく WOW64 スレッドに焦点を当てた 64 ビット デバッガーを回避できます。

多くの事後デバッガー (Windows 事後デバッガー用デバッグ ツールなど) では、インストール コマンドを 2 回実行する必要があります。x86 バージョンで 1 回、x64 バージョンで 1 回。 たとえば、WinDbg を対話型事後デバッガーとして使用する場合、 windbg.exe -I コマンドはバージョンごとに 1 回、2 回実行されます。

64 ビット インストール:

C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\windbg.exe –I

これにより、レジストリ キーがこれらの値で更新されます。

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AeDebug
Debugger = "C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\windbg.exe" -p %ld -e %ld –g

32 ビット インストール:

C:\Program Files (x86)\Windows Kits\10\Debuggers\x86\windbg.exe –I

これにより、レジストリ キーがこれらの値で更新されます。

HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows NT\CurrentVersion\AeDebug
Debugger = "C:\Program Files (x86)\Windows Kits\10\Debuggers\x86\windbg.exe" -p %ld -e %ld –g

事後デバッガーの構成

Windows 用デバッグ ツール

Windows デバッガー用のデバッグ ツールでは、すべてのサポートが事後デバッガーとして設定されます。 install コマンドは、プロセスを対話形式でデバッグする予定です。

WinDbg

事後デバッガーを WinDbg に設定するには、次を実行 windbg -Iします。 I(大文字にする必要があります)。このコマンドを使用すると、成功または失敗のメッセージが表示されます。 32 ビット アプリケーションと 64 ビット アプリケーションの両方を操作するには、64 と 32 の両方のデバッガーに対してコマンドを実行します。

C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\windbg.exe –I
C:\Program Files (x86)\Windows Kits\10\Debuggers\x86\windbg.exe –I

これにより、実行時に AeDebug レジストリ エントリが構成 windbg -I されます。

Debugger = "<Path>\WinDbg -p %ld -e %ld -g"
Auto = 1

例では、 <Path> はデバッガーが配置されているディレクトリです。

p パラメーターと -e パラメーターは、前に説明したように、プロセス ID とイベントを渡します。

g は g (Go) コマンドを WinDbg に渡し、現在の命令から実行を続行します。

メモ g (Go) コマンドを渡すと、大きな問題が発生します。 この方法の問題は、例外が常に繰り返されるとは限りません。通常は、コードの再起動時に一時的な状態が存在しなくなったためです。 この問題の詳細については、「 .jdinfo (JIT_DEBUG_INFOを使用する)」を参照してください。

この問題を回避するには、.jdinfo または .dump /j を使用します。 この方法により、デバッガーは目的のコードエラーのコンテキストに入ることができます。 詳細については、このトピック の後半の「Just In Time (JIT) デバッグ 」を参照してください。

CDB

事後デバッガーを CDB に設定するには、 cdb -iae (Install AeDebug) または cdb -iaecKeyString (Install AeDebug with Command) を実行します。

C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\cdb.exe -iae
C:\Program Files (x86)\Windows Kits\10\Debuggers\x86\cdb.exe -iae

iaec パラメーターを使用する場合、KeyString は、事後デバッガーを起動するために使用されるコマンド ラインの末尾に追加する文字列を指定します。 KeyString にスペースが含まれている場合は、引用符で囲む必要があります。

C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\cdb.exe -iaec [KeyString]
C:\Program Files (x86)\Windows Kits\10\Debuggers\x86\cdb.exe -iaec [KeyString]

このコマンドでは、成功した場合は何も表示されません。失敗した場合はエラー メッセージが表示されます。

Ntsd

事後デバッガーを NTSD に設定するには、 ntsd -iae (Install AeDebug) または ntsd -iaecKeyString (Install AeDebug with Command) を実行します。

C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\ntsd.exe -iae
C:\Program Files (x86)\Windows Kits\10\Debuggers\x86\ntsd.exe -iae

iaec パラメーターを使用する場合、KeyString は、事後デバッガーを起動するために使用されるコマンド ラインの末尾に追加する文字列を指定します。 KeyString にスペースが含まれている場合は、引用符で囲む必要があります。

C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\ntsd.exe -iaec [KeyString]
C:\Program Files (x86)\Windows Kits\10\Debuggers\x86\ntsd.exe -iaec [KeyString]

このコマンドは成功した場合は何も表示しません。失敗した場合は新しいコンソール ウィンドウにエラーが表示されます。

メモ -p %ld -e %ld -g パラメーターは常に事後デバッガーのコマンド ラインに最初に表示されるため、-iaec スイッチを使用して -server パラメーターを指定しないでください。-server はコマンド ラインに最初に表示されない限り機能しないためです。 このパラメーターを含む事後デバッガーをインストールするには、レジストリを手動で編集する必要があります。

Visual Studio JIT デバッガー

Visual Studio がインストールされている場合、vsjitdebugger.exeは事後デバッガーとして登録されます。 Visual Studio JIT デバッガーは、プロセスを対話形式でデバッグする予定です。

Debugger = "C:\WINDOWS\system32\vsjitdebugger.exe" -p %ld -e %ld

Visual Studio が更新または再インストールされた場合、このエントリは再書き込みされ、設定された代替値が上書きされます。

ウィンドウ Sysinternals ProcDump

Windows Sysinternals ProcDump ユーティリティは、事後ダンプ キャプチャにも使用できます。 ProcDump の使用とダウンロードの詳細については、「 ProcDump」を参照してください。

.dump WinDbg コマンドと同様に、ProcDump はクラッシュのダンプを対話形式でキャプチャできます。 キャプチャは、任意の Windows システム セッションで発生する可能性があります。

ダンプ ファイル キャプチャが完了すると ProcDump が終了し、WER によってエラーが報告され、エラープロセスが終了します。

procdump のインストールに使用 procdump -i し、32 ビットと 64 ビットの事後デバッグの両方について ProcDump をアンインストールします。

<Path>\procdump.exe -i

インストールとアンインストールのコマンドでは、成功時に変更されたレジストリ値とエラー時のエラーが出力されます。

レジストリの ProcDump コマンド ライン オプションは、次に設定されます。

Debugger = <Path>\ProcDump.exe -accepteula -j "<DumpFolder>" %ld %ld %p

ProcDump では、PID、イベント、JIT_DEBUG_INFOの 3 つのパラメーターがすべて使用されます。 JIT_DEBUG_INFO パラメーターの詳細については、次 の「Just In Time (JIT) デバッグ 」を参照してください。

キャプチャされたダンプのサイズは、サイズ オプションが設定されていない Mini (process/threads/handles/modules/address space)、-mp が設定された MiniPlus (Mini plus MEM_PRIVATE ページ)、または -ma が設定された完全 (すべてのメモリ - ".dump /mA" に相当) に既定で設定されます。

十分なドライブ領域を持つシステムの場合は、フル (ma) キャプチャをお勧めします。

すべてのメモリ キャプチャを指定するには、-i オプションと共に -ma を使用します。 必要に応じて、ダンプ ファイルのパスを指定します。

<Path>\procdump.exe -ma -i c:\Dumps

ドライブ領域が限られているシステムの場合は、MiniPlus (-mp) キャプチャをお勧めします。

<Path>\procdump.exe -mp -i c:\Dumps

ダンプ ファイルを保存するフォルダーは省略可能です。 既定値は現在のフォルダーです。 フォルダーは、C:\Windows\Temp で使用されているものと同じかそれ以上の ACL で保護されている必要があります。フォルダーに関連するセキュリティの管理の詳細については、「 事後デバッグ中のセキュリティ」を参照してください。

事後デバッガーとして ProcDump をアンインストールし、前の設定を復元するには、-u (アンインストール) オプションを使用します。

<Path>\procdump.exe -u

ProcDump の詳細については、Microsoft Press によって公開された Mark Russinovich および Aaron Margosis による ProcDumpWindows SysInternals Administrator's Reference を参照してください。

Just In Time (JIT) デバッグ

エラーが発生しているアプリケーションへのコンテキストの設定

前述のように、JIT_DEBUG_INFO パラメーターを使用してクラッシュの原因となった例外にコンテキストを設定することが非常に望ましいです。 詳細については、「 .jdinfo (JIT_DEBUG_INFOを使用する)」を参照してください。

Windows 用デバッグ ツール

この例では、.jdinfo <address> コマンドを使用して追加の例外情報を表示し、コンテキストを例外の場所に変更する初期コマンド (-c) を実行するようにレジストリを編集する方法を示します (.ecxr の使用方法と同様に、コンテキストを例外レコードに設定します)。

Debugger = "<Path>\windbg.exe -p %ld -e %ld -c ".jdinfo 0x%p"
Auto = 1

%p パラメーターは、ターゲット・プロセスのアドレス・スペース内のJIT_DEBUG_INFO構造体のアドレスです。 %p パラメーターは 0x で事前に追加され、16 進値として解釈されます。 詳細については、「 .jdinfo (JIT_DEBUG_INFOを使用する)」を参照してください。

32 ビット アプリと 64 ビット アプリの組み合わせをデバッグするには、32 ビットと 64 ビットの両方のレジストリ キー (前述) を構成し、64 ビットと 32 ビットのWinDbg.exeの場所への適切なパスを設定します。

.dump を使用したダンプ ファイルの作成

JIT_DEBUG_INFO データを含む障害が発生するたびにダンプ ファイルをキャプチャするには、.dump /j <アドレスを使用します>。

<Path>\windbg.exe -p %ld -e %ld -c ".dump /j %p /u <DumpPath>\AeDebug.dmp; qd"

/u オプションを使用して一意のファイル名を生成し、複数のダンプ ファイルを自動的に作成できるようにします。 オプションの詳細については、「 .dump (ダンプ ファイルの作成)」を参照してください。

作成されたダンプには、JITDEBUG_INFO データが既定の例外コンテキストとして格納されます。 .jdinfo を使用して例外情報を表示し、コンテキストを設定する代わりに、.exr -1 を使用して例外レコードを表示し、.ecxr を使用してコンテキストを設定します。 詳細については、 .exr (例外レコードの表示).ecxr (例外コンテキスト レコードの表示) を参照してください。

Windows エラー報告 - q / qd

デバッグ セッションの終了方法によって、Windows エラー報告がエラーを報告するかどうかが決まります。

デバッガーを閉じる前に qd を使用してデバッグ セッションをデタッチすると、WER によってエラーが報告されます。

デバッグ セッションが q を使用して終了した場合 (またはデタッチせずにデバッガーが閉じている場合)、WER はエラーを報告しません。

コマンド文字列の末尾に ;q または ;qd を追加して、目的の動作を呼び出します。

たとえば、CDB がダンプをキャプチャした後に WER がエラーを報告できるようにするには、このコマンド文字列を構成します。

<Path>\cdb.exe -p %ld -e %ld -c ".dump /j 0x%p /u c:\Dumps\AeDebug.dmp; qd"

この例では、WinDbg がダンプをキャプチャした後に WER がエラーを報告できるようにします。

<Path>\windbg.exe -p %ld -e %ld -c ".dump /j %p /u <DumpPath>\AeDebug.dmp; qd""

セキュリティの脆弱性

他のユーザーと共有するコンピューターで事後デバッグを有効にすることを検討している場合は、「 事後デバッグ中のセキュリティ」を参照してください。