共用方式為


讀取錯誤檢查回呼資料

許多驅動程式都會提供 錯誤檢查回呼常式。 當 Windows 發出錯誤檢查時,它會在關閉系統之前呼叫這些常式。 這些常式可以指定並寫入記憶體區域,稱為回呼資料和次要回呼資料

BugCheckCallback 使用 KBUGCHECK_CALLBACK_ROUTINE
此常式所寫入的資料會成為 回呼資料的一部分。 資料不會包含在損毀傾印檔案中。

BugCheckSecondaryDumpDataCallback 使用 KBUGCHECK_REASON_CALLBACK_ROUTINE
此常式所寫入的資料會成為 次要回呼資料的一部分。 資料會包含在損毀傾印檔案中。

BugCheckAddPagesCallback 使用 KBUGCHECK_REASON_CALLBACK_ROUTINE
此常式指定的頁面會成為 回呼資料的一部分。 這些頁面中的資料會包含在損毀傾印檔案中。

偵錯工具可用的回呼和次要回呼資料量取決於數個因素:

  • 如果您要執行損毀系統的即時偵錯,則可以使用 BugCheckCallback 所撰寫或 由 BugCheckAddPagesCallback 所指定的回呼資料。 次要回呼資料將無法使用,因為它不會儲存在任何固定記憶體位置中。

  • 如果您要偵錯完整記憶體傾印或核心記憶體傾印,則 BugCheckAddPagesCallback 所指定的回呼資料,以及 BugCheckSecondaryDumpDataCallback 所寫入的次要回呼資料將可供使用。 BugCheckCallback所寫入的回呼資料將無法使用。

  • 如果您要偵錯小型記憶體傾印,將無法使用回呼資料。 次要回呼資料將可供使用。

如需這些不同傾印檔案大小的詳細資訊,請參閱 各種 Kernel-Mode 傾印檔案

顯示回呼資料

若要顯示錯誤檢查回呼資料,您可以使用 !bugdump 延伸模組。

如果沒有任何參數, !bugdump 將會顯示所有回呼的資料。

若要檢視一個特定回呼常式的資料,請使用 !bugdump元件,其中 Component 是註冊該常式時傳遞至 KeRegisterBugCheckCallback 的相同參數。

顯示次要回呼資料

有兩種方法可用來顯示次要回呼資料。 您可以使用 .enumtag 命令,也可以撰寫自己的偵錯工具擴充功能。

次要回呼資料的每個區塊都會由 GUID 標籤識別。 此標記是由傳遞至BugCheckSecondaryDumpDataCallback之 (KBUGCHECK_SECONDARY_DUMP_DATA) ReasonSpecificData參數的Guid欄位所指定。

.enumtag (列舉次要回呼資料) 命令不是非常精確的檢測。 它會顯示每個次要資料區塊,其中顯示標記,然後以十六進位和 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 會傳回失敗狀態碼。

如果兩個區塊具有相同的 GUID 標記,則會傳回第一個相符的區塊,而第二個區塊將會無法存取。

如果您不確定區塊的 GUID 標記,您可以使用 IDebugDataSpaces3::StartEnumTaggedIDebugDataSpaces3::GetNextTaggedIDebugDataSpaces3::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;

偵錯回呼常式

您也可以偵錯回呼常式本身。 回呼常式內的中斷點就像任何其他中斷點一樣運作。

如果回呼常式造成第二個錯誤檢查,則會先處理這個新的錯誤檢查。 不過,Windows 不會重複停止程式的某些部分,例如,它不會寫入第二個損毀傾印檔案。 藍色畫面上顯示的 [停止] 程式碼將會是第二個錯誤檢查碼。 如果附加核心偵錯工具,這兩個錯誤檢查的相關訊息通常會出現。