バグ チェック コールバック データの読み取り
多くのドライバーはバグ チェック コールバック ルーチンを提供します。 Windows がバグ チェックを発行するとき、システムをシャットダウンする前にこれらのルーチンを呼び出します。 これらのルーチンは、コールバック データおよびセカンダリ コールバック データと呼ばれるメモリ領域を指定して書き込むことができます。
BugCheckCallback は KBUGCHECK_CALLBACK_ROUTINE を使用します
このルーチンによって書き込まれたデータはコールバック データの一部になります。 データはクラッシュ ダンプ ファイルには含まれません。
BugCheckSecondaryDumpDataCallbackKBUGCHECK_REASON_CALLBACK_ROUTINE を使用する
このルーチンによって書き込まれたデータは、2 次コールバック データの一部になります。 データはクラッシュ ダンプ ファイルに含まれています。
BugCheckAddPagesCallback は KBUGCHECK_REASON_CALLBACK_ROUTINE を使用します
このルーチンで指定されたページはコールバック データの一部になります。 これらのページのデータはクラッシュ ダンプ ファイルに含まれています。
デバッガーが使用できるコールバック データとセカンダリ コールバック データの量は、いくつかの要因によって異なります。
クラッシュしたシステムのライブ デバッグを実行している場合は、BugCheckCallback によってすでに書き込まれたコールバック データ、または BugCheckAddPagesCallback によって指定されたコールバック データが利用可能になります。 セカンダリ コールバック データは固定メモリの場所に保存されないため、利用できません。
完全メモリ ダンプまたはカーネル メモリ ダンプをデバッグしている場合は、BugCheckAddPagesCallback によって指定されたコールバック データと、BugCheckSecondaryDumpDataCallback によって書き込まれたセカンダリ コールバック データが利用可能になります。 BugCheckCallback によって書き込まれたコールバック データは利用できなくなります。
小規模メモリ ダンプをデバッグしている場合、コールバック データは利用できません。 セカンダリ コールバック データが利用可能になります。
これらのさまざまなダンプ ファイル サイズの詳細については、「さまざまなカーネル モード ダンプ ファイル」を参照してください。
コールバックデータの表示
バグ チェック コールバック データを表示するには、!bugdump 拡張機能を使用できます。
パラメータを指定しないと、!bugdump はすべてのコールバックのデータを表示します。
1 つの特定のコールバック ルーチンのデータを表示するには、!bugdumpComponent を使用します。ここで、Component は、そのルーチンが登録されたときに KeRegisterBugCheckCallback に渡されたパラメータと同じです。
セカンダリ コールバック データの表示
セカンダリ コールバック データを表示するには 2 つの方法があります。 .enumtag コマンドを使用することも、独自のデバッガー拡張機能を作成することもできます。
セカンダリ コールバック データの各ブロックは GUID タグによって識別されます。 このタグは、BugCheckSecondaryDumpDataCallback に渡される (KBUGCHECK_SECONDARY_DUMP_DATA)ReasonSpecificData パラメーターの Guid フィールドによって指定されます。
.enumtag (セカンダリ コールバック データの列挙) コマンドは、あまり正確な手段ではありません。 すべてのセカンダリ データ ブロックを表示し、タグを表示してから、データを 16 進数および ASCII 形式で表示します。 一般に、どのタグが二次データ ブロックに実際に使用されているかを判断する場合にのみ役立ちます。
このデータをより実用的な方法で使用するには、独自のデバッガー拡張機能を作成することをお勧めします。 この拡張機能は、dbgeng.h ヘッダー ファイル内のメソッドを呼び出す必要があります。 詳細については、「新しいデバッガ拡張機能の作成」を参照してください。
セカンダリ データ ブロックの GUID タグがわかっている場合、拡張機能はメソッド IDebugDataSpaces3::ReadTagged を使用してデータにアクセスする必要があります。 そのプロトタイプは次のとおりです。
STDMETHOD(ReadTagged)(
THIS_
IN LPGUID Tag,
IN ULONG Offset,
OUT OPTIONAL PVOID Buffer,
IN ULONG BufferSize,
OUT OPTIONAL PULONG TotalSize
) PURE;
このメソッドの使用方法の例を次に示します。
UCHAR RawData[MY_DATA_SIZE];
GUID MyGuid = .... ;
Success = DataSpaces->ReadTagged( &MyGuid, 0, RawData,
sizeof(RawData), NULL);
小さすぎる BufferSize を指定すると、ReadTagged は成功しますが、要求されたバイト数のみが Buffer に書き込まれます。 大きすぎる BufferSize を指定すると、ReadTagged は成功しますが、実際のブロック サイズのみが Buffer に書き込まれます。 TotalSize のポインターを指定すると、ReadTagged はそれを使用して実際のブロックのサイズを返します。 ブロックにアクセスできない場合、ReadTagged は失敗ステータス コードを返します。
2 つのブロックが同一の GUID タグを持つ場合、最初に一致したブロックが返され、2 番目のブロックにはアクセスできなくなります。
ブロックの GUID タグがわからない場合は、IDebugDataSpaces3::StartEnumTagged, IDebugDataSpaces3::GetNextTagged, および IDebugDataSpaces3::EndEnumTagged メソッドを使用して、タグ付きブロックを列挙できます。 それらのプロトタイプは次のとおりです。
STDMETHOD(StartEnumTagged)(
THIS_
OUT PULONG64 Handle
) PURE;
STDMETHOD(GetNextTagged)(
THIS_
IN ULONG64 Handle,
OUT LPGUID Tag,
OUT PULONG Size
) PURE;
STDMETHOD(EndEnumTagged)(
THIS_
IN ULONG64 Handle
) PURE;
コールバック ルーチンのデバッグ
コールバック ルーチン自体をデバッグすることも可能です。 コールバック ルーチン内のブレークポイントは、他のブレークポイントと同様に機能します。
コールバック ルーチンによって 2 番目のバグ チェックが発生した場合、この新しいバグ チェックが最初に処理されます。 ただし、Windows は停止プロセスの特定の部分を繰り返しません。たとえば、2 番目のクラッシュ ダンプ ファイルは書き込まれません。 ブルースクリーンに表示されるStopコードが2つ目のバグチェックコードとなります。 カーネル デバッガが接続されている場合、通常は両方のバグ チェックに関するメッセージが表示されます。