例外とイベントの制御

ユーザー モードおよびカーネル モード のアプリケーションで、さまざまな方法で例外をキャッチして処理することができます。 アクティブなデバッガー、事後デバッガー、または内部エラー処理ルーチンはいずれも、例外を処理する一般的な方法です。

これらのさまざまな例外ハンドラーの優先順位の詳細については、「事後デバッグの有効化」を参照してください。

Microsoft Windows オペレーティング システムでデバッガーに例外処理を許可している場合、例外を生成したアプリケーションにデバッガーが割り込みます。 つまり、アプリケーションが停止し、デバッガーがアクティブになります。 その後で、デバッガーは、何らかの方法で例外を処理するか、状況を分析することができます。 さらに、デバッガーは、プロセスを終了するか、実行を再開できます。

デバッガーが例外を無視してアプリケーションの実行を継続させる場合、オペレーティング システムは、デバッガーが存在しなかったかのように他の例外ハンドラーを探します。 例外が処理された場合、アプリケーションの実行は続行されます。 ただし、例外が処理されないままの場合、その状況を処理する 2 番目の機会がデバッガーに与えられます。

デバッガーを使用した例外の分析

例外またはイベントによってデバッガーが割り込んだときは、ユーザーはデバッガーを使用して、実行中のコードと、アプリケーションが使用しているメモリを調べることができます。 特定の数量を変更したり、アプリケーション内の別のポイントにジャンプしたりすることで、例外の原因を取り除くことができる場合があります。

gh (例外処理ありで実行) コマンドまたは gn (例外処理なしで実行) コマンドを発行することで、実行を再開できます。

デバッガーが例外処理の 2 番目の機会を得たときに gn コマンドを発行すると、アプリケーションは終了します。

カーネル モード例外

カーネル モード コードで発生する例外は、ユーザー モードの例外よりも深刻です。 カーネル モードの例外が処理されない場合は、バグ チェックが発行され、システムが停止します。

ユーザー モードの例外の場合と同様に、カーネル モード デバッガーがシステムにアタッチされている場合、バグ チェック画面 (ブルー スクリーンとも呼ばれます) が表示される前に、デバッガーに通知が送られます。 デバッガーがアタッチされていない場合、バグ チェック画面が表示されます。 この場合、オペレーティング システムによってクラッシュ ダンプ ファイルが作成される可能性があります。

デバッガーからの例外とイベントの制御

指定された例外とイベントに特定の方法で対応するように、デバッガーを構成できます。

デバッガーは、個々の例外またはイベントの中断状態を設定できます。

  • イベントでは、発生すると直ちにデバッガーに割り込ませることができます ("ファースト チャンス")。

  • イベントでは、他のエラー ハンドラーに応答の機会が与えられた後に、割り込ませることができます ("セカンド チャンス")。

  • イベントでは、デバッガーにメッセージを送信したうえで、実行を継続することもできます。

  • デバッガーは、イベントを無視できます。

デバッガーは、個々の例外とイベントの処理状態を設定することもできます。 デバッガーは、処理された例外または未処理の例外と同様にイベントを処理できます。 (もちろん、実際にはエラーではないイベントは、処理を必要としません。)

以下のいずれかの操作を行って、中断状態と処理状態を制御できます。

  • SXESXDSXNSXI のいずれかのコマンドをデバッガー コマンド ウィンドウで使用します。

  • (CDB および NTSD) -x-xe-xd-xn-xi のいずれかのオプションを、コマンド ラインで使用します。

  • (CDB、NTSD、KD) Tools.ini ファイルで、sxe または sxd キーワードを使用します。

  • (WinDbg のみ) [デバッグ] メニューの [イベント フィルター] を選択して [イベント フィルター] ダイアログ ボックスを開き、目的のオプションを選択します。

SX\* コマンド、-x\* コマンド ライン オプション、sx\* Tools.ini キーワードは、通常、指定されたイベントの中断状態を設定します。 -h オプションを追加することで、代わりに処理状態を設定することもできます。

4 つの特殊なイベント コード (cchcbpecssec) があり、これらは常に、中丹状態ではなく処理状態を指定します。

.lastevent (最新のイベントの表示) コマンドを使用すると、最も新しい例外またはイベントを表示できます。

中断状態の制御

例外またはイベントの中断状態を設定するときに、以下のオプションを使用できます。

コマンド ステータス名 説明

SXE または -xe

休憩

(有効)

この例外が発生すると、デバッガーが即座にターゲットに割り込みます。 この割り込みは、他のエラー ハンドラーがアクティブになる前に発生します。 この方法は、ファースト チャンス処理と呼ばれます。

SXD または -xd

セカンド チャンスの割り込み

(無効)

この種類のファースト チャンス例外では、デバッガーは割り込みません (ただしメッセージは表示されます)。 他のエラー ハンドラーがこの例外に対処できない場合は、実行が停止し、デバッガーがターゲットが割り込みます。 この方法は、セカンド チャンス処理と呼ばれます。

SXN または -xn

出力

通知

この例外が発生したときは、デバッガーはターゲット アプリケーションに一切割り込みません。 ただし、この例外についてユーザーに通知するメッセージが表示されます。

SXI または -xi

Ignore

この例外が発生したときは、デバッガーはターゲット アプリケーションに割り込まず、メッセージも表示されません。

SX* 設定によって例外が予想されていない場合、セカンド チャンスでデバッガーがターゲット アプリケーションに割り込みます。 イベントの既定の状態については、このトピックの「イベント定義と既定値」セクションを参照してください。

WinDbg グラフィカル インターフェイスを使用して中断状態を設定するには、[デバッグ] メニューの [イベント フィルター] を選択し、[イベント フィルター] ダイアログ ボックスのリストから目的のイベントを選択してから、[有効][無効][出力][無視] のいずれかを選択します。

処理状態の制御

gh (例外処理ありで実行) コマンドを使用しない限り、すべてのイベントは未処理と見なされます。

sx\* コマンドを -h オプションと共に使用しない限り、すべての例外は未処理と見なされます。

さらに、SX* オプションでは、無効なハンドル、STATUS_BREAKPOINT 中断命令、および単一ステップの例外の処理状態を構成できます。 (この構成はそれぞれの中断構成とは別のものです。) 中断状態を構成すると、これらのイベントに、それぞれ chbpesse という名前が付けられます。 処理状態を構成すると、これらのイベントに、それぞれ hcbpecssec の名前が付けられます。 (イベントの完全な一覧については、後述の「イベントの定義と既定値」セクションを参照してください。)

Ctrl + C イベント (cc) については、処理状態は構成できますが、中断状態は構成できません。 アプリケーションが Ctrl + C イベントを受け取った場合、常にデバッガーがアプリケーションに割り込みます。

SX* コマンドを cchcbpecssec の各イベントに対して使用するか、SX* コマンドを -h オプションと共に例外に対して使用すると、以下のアクションが発生します。

コマンド ステータス名 説明

SXE

Handled

このイベントは、実行が再開されたときに処理済みと見なされます。

SXD、SXN、SXI

未処理

このイベントは、実行が再開されたときに未処理と見なされます。

WinDbg グラフィカル インターフェイスを使用して処理状態を設定するには、[デバッグ] メニューの [イベント フィルター] を選択し、[イベント フィルター] ダイアログ ボックスのリストから目的のイベントを選択してから、[処理済み] または [未処理] を選択します。

自動コマンド

デバッガーでは、イベントまたは例外によってデバッガーが割り込んだ場合に自動的に実行されるコマンドを設定することもできます。 ファースト チャンスの中断用のコマンド文字列と、セカンド チャンスの中断用のコマンド文字列を設定できます。 これらの文字列は、SX\* コマンドまたは [デバッグ] | [イベント フィルター] コマンドで設定できます。 各コマンド文字列には、複数のコマンドをセミコロンで区切って含めることができます。

これらのコマンドは、中断状態に関係なく実行されます。 つまり、中断状態が "無視" の場合、コマンドは引き続き実行されます。 中断状態が "セカンド チャンスの中断" の場合、他の例外ハンドラーが関与する前に、例外が最初に発生したときにファースト チャンスのコマンドが実行されます。 コマンド文字列の最後に、g (実行)gh (例外処理ありで実行)、または gn (例外処理なしで実行) などの実行コマンドを使用できます。

イベントの定義と既定値

以下の例外の中断状態または処理状態を変更できます。 それぞれの既定の中断状態が示されています。

以下の例外の既定の処理状態は、常に "未処理" です。 この状態の変更には注意してください。 この状態を "処理済み" にすると、この種類のファースト チャンスとセカンド チャンスのすべての例外が処理済みと見なされ、この構成はすべての例外処理ルーチンをバイパスします。

イベント コード 意味 既定の中断状態

asrt

アサーション エラー

休憩

av

アクセス違反

休憩

dm

データの不整合

休憩

dz

ゼロによる整数除算

休憩

c000008e

ゼロによる浮動小数点除算

休憩

eh

C++ EH 例外

セカンド チャンスの割り込み

gp

ガード ページ違反

休憩

ii

無効な命令

セカンド チャンスの割り込み

iov

整数オーバーフロー

休憩

ip

ページ内 I/O エラー

休憩

isc

無効なシステム呼び出し

休憩

lsq

無効なロック シーケンス

休憩

sbo

スタックのバッファー オーバーフロー

休憩

sov

スタック オーバーフロー

休憩

wkd

Wake デバッガー

休憩

aph

アプリケーションのハング

プロセスが応答を停止した (つまりハングした) と Windows オペレーティング システムが判断した場合に、この例外がトリガーされます。

休憩

3c

子アプリケーションの終了

セカンド チャンスの割り込み

chhc

ハンドルが無効です

休憩

番号

任意の番号付き例外

セカンド チャンスの割り込み

特定のアドレスの asrt 中断状態は、ah (アサーションの処理) コマンドで上書きできます。 ch および hc イベント コードは、同じ例外を参照します。 中断状態を制御するときは、sx* ch を使用します。 処理状態を制御するときは、sx* hc を使用します。

以下の例外の中断状態または処理状態を変更できます。 それぞれの既定の中断状態が示されています。

以下の例外の既定の処理状態は、常に "処理済み" です。 これらの例外はデバッガーとの通信に使用されるため、通常は状態を "未処理" に変更しないでください。 この状態により、デバッガーが例外を無視した場合に、他の例外ハンドラーが例外をキャッチします。

アプリケーションは、DBG_COMMAND_EXCEPTION (dbce) を使用してデバッガーと通信できます。 この例外はブレークポイントに似ていますが、この例外が発生したときに SX* コマンドを使用して特定の方法で対応できる点が異なります。

イベント コード 意味 既定の中断状態

dbce

特殊なデバッガー コマンドの例外

Ignore

vcpp

特殊な Visual C++ の例外

Ignore

wos

WOW64 単一ステップの例外

休憩

wob

WOW64 ブレークポイント例外

休憩

sse
ssec

単一ステップの例外

休憩

bpe
bpec

ブレークポイント例外

休憩

cce
cc

Ctrl + C または Ctrl + Break

この例外は、ターゲットがコンソール アプリケーションであり、Ctrl + C または Ctrl + Break が渡された場合にトリガーされます。

休憩

前掲の表の最後の 3 つの例外に、2 つの異なるイベント コードがあります。 中断状態を制御するときは、ssebpecce を使用します。 処理状態を制御するときは、ssecbpeccc を使用します。

以下の例外は、マネージド コードをデバッグする場合に役立ちます。

イベント コード 意味 既定のステータス

clr

共通言語ランタイムの例外

セカンド チャンスの割り込み

未処理

clrn

共通言語ランタイム通知の例外

セカンド チャンスの割り込み

処理済み

以下のイベントの中断状態を変更できます。 これらのイベントは例外ではないため、処理状態は関係ありません。

イベント コード 意味 既定の中断状態

ser

システム エラー

Ignore

cpr[:Process]

プロセス作成

このイベントの中断状態の設定は、ユーザー モード デバッグにのみ適用されます。 このイベントはカーネル モードでは発生しません。

このイベントは、CDB または WinDbg で子プロセスのデバッグをアクティブ化してある場合にのみ制御できます。それには、-o コマンド ライン オプション または .childdbg (子プロセスのデバッグ) コマンドを使用します。

プロセス名には、オプションでファイル名拡張子と、ワイルドカード文字としてアスタリスク () または疑問符 (?) を含めることができます。 デバッガーは、最新の cpr 設定のみを記憶します。 個別のプロセスに対する個別の設定はサポートされていません。 cprProcess の間にはコロンまたはスペースを入れます。

Process を省略した場合、この設定は、すべての子プロセスの作成に適用されます。

Ignore

epr[:Process]

プロセスの終了

このイベントの中断状態の設定は、ユーザー モード デバッグにのみ適用されます。 このイベントはカーネル モードでは発生しません。

このイベントは、CDB または WinDbg で子プロセスのデバッグをアクティブ化してある場合にのみ制御できます。それには、-o コマンド ライン オプション または .childdbg (子プロセスのデバッグ) コマンドを使用します。

プロセス名には、オプションでファイル名拡張子と、ワイルドカード文字としてアスタリスク () または疑問符 (?) を含めることができます。 デバッガーは、最新の epr 設定のみを記憶します。 個別のプロセスに対する個別の設定はサポートされていません。 eprProcess の間にはコロンまたはスペースを入れます。

Process を省略した場合、この設定は、すべての子プロセスの終了に適用されます。

Ignore

ct

スレッドの作成

Ignore

et

スレッドの終了

Ignore

ld[:Module]

モジュールの読み込み

Module を指定する場合、この名前のモジュールが読み込まれると割り込みが発生します。 Module には、モジュールの名前またはアドレスを指定できます。 名前を使用する場合、Module には、さまざまなワイルドカード文字や指定子を含めることができます。 (構文の詳細については、「文字列ワイルドカード構文」を参照してください。)

デバッガーは、最新の d 設定のみを記憶します。 個別のモジュールに対する個別の設定はサポートされていません。 ldModule の間にはコロンまたはスペースを入れます。

Module を省略した場合、任意のモジュールが読み込まれるとイベントがトリガーされます。

出力

ud[:Module]

モジュールのアンロード

Module を指定する場合、この名前のモジュールまたはこのベース アドレスにあるモジュールがアンロードされると、中断が発生します。 Module には、モジュールの名前またはアドレスを指定できます。 名前を使用する場合、Module には、正確な名前を指定するか、ワイルドカード文字を含めることができます。 Module が正確な名前である場合、現在のデバッガー モジュール リストを使用して即座にベース アドレスに解決され、アドレスとして格納されます。 Module にワイルドカード文字が含まれる場合、アンロード イベントが発生したときに後で照合できるように、パターン文字列が保持されます。

まれに、デバッガーにはアンロード イベントの名前情報が保持されず、ベース アドレスでのみ照合することがあります。 したがって、Module にワイルドカード文字列が含まれる場合、デバッガーはこの特定のアンロードの場合に名前の照合を実行できず、任意のモジュールがアンロードされると中断します。

デバッガーは、最新の ud 設定のみを記憶します。 個別のモジュールに対する個別の設定はサポートされていません。 udModule の間にはコロンまたはスペースを入れます。

Module を省略した場合、任意のモジュールが読み込まれるとイベントがトリガーされます。

出力

out[:Output]

ターゲット アプリケーションの出力

Output を指定する場合、指定されたパターンと一致する出力を受け取ったときにのみ中断が発生します。 Output には、さまざまなワイルドカード文字と指定子を含めることができます。 (構文の詳細については、「文字列ワイルドカード構文」を参照してください)。ただし、Output にコロンまたはスペースを含めることはできません。 照合では大文字と小文字が区別されません。 outOutput の間にはコロンまたはスペースを入れます。

Ignore

ibp

初期ブレークポイント

(このイベントは、デバッグ セッションの開始時およびターゲット コンピューターの再起動後に発生します)。

ユーザー モードの場合: 中断。 -gコマンド ライン オプションを使用して、このステータスを "無視" に変更できます。

カーネル モードの場合: 無視。 この状態は、さまざまな方法で "有効" に変更できます。 この状態を変更する方法の詳細については、「ターゲット コンピューターのクラッシュと再起動」を参照してください。

iml

初期モジュール読み込み

(カーネル モードのみ)

無視。 この状態は、さまざまな方法で "中断" に変更できます。 この状態を変更する方法の詳細については、「ターゲット コンピューターのクラッシュと再起動」を参照してください。