Freigeben über


Lesen von Bug Check-Rückrufdaten

Viele Treiber bieten Rückrufroutinen zur Fehlerüberprüfung. Wenn Windows eine Fehlerüberprüfung ausgibt, ruft es diese Routinen auf, bevor das System heruntergefahren wird. Diese Routinen können Speicherbereiche angeben und schreiben, die als Rückrufdaten und sekundäre Rückrufdaten bezeichnet werden.

BugCheckCallback verwenden KBUGCHECK_CALLBACK_ROUTINE
Von dieser Routine geschriebene Daten werden Teil von Rückrufdaten. Die Daten sind nicht in der Absturzabbilddatei enthalten.

BugCheckSecondaryDumpDataCallback verwenden KBUGCHECK_REASON_CALLBACK_ROUTINE
Von dieser Routine geschriebene Daten werden Teil sekundärer Rückrufdaten. Die Daten sind in der Absturzabbilddatei enthalten.

BugCheckAddPagesCallback verwenden KBUGCHECK_REASON_CALLBACK_ROUTINE
Von dieser Routine angegebene Seiten werden Teil von Rückrufdaten. Die Daten auf diesen Seiten sind in der Absturzabbilddatei enthalten.

Die Menge an Rückruf- und sekundären Rückrufdaten, die dem Debugger zur Verfügung stehen, hängt von mehreren Faktoren ab:

  • Wenn Sie das Livedebuggen eines abgestürzten Systems durchführen, sind Rückrufdaten verfügbar, die bereits von BugCheckCallback geschrieben oder von BugCheckAddPagesCallback angegeben wurden. Sekundäre Rückrufdaten sind nicht verfügbar, da sie nicht an einem festen Speicherort gespeichert werden.

  • Wenn Sie ein vollständiges Speicherabbild oder Kernelspeicherabbild debuggen, sind Rückrufdaten verfügbar, die von BugCheckAddPagesCallback angegeben wurden, und sekundäre Rückrufdaten, die von BugCheckSecondaryDumpDataCallback geschrieben wurden. Rückrufdaten, die von BugCheckCallback geschrieben wurden, sind nicht verfügbar.

  • Wenn Sie ein Small Memory Dump debuggen, sind Rückrufdaten nicht verfügbar. Sekundäre Rückrufdaten sind verfügbar.

Weitere Informationen zu diesen verschiedenen Speicherabbilddateigrößen finden Sie unter Sorten von Kernel-Mode Dumpdateien .

Anzeigen von Rückrufdaten

Zum Anzeigen von Rückrufdaten zur Fehlerüberprüfung können Sie die Erweiterung !bugdump verwenden.

Ohne Parameter zeigt !bugdump Daten für alle Rückrufe an.

Um Daten für eine bestimmte Rückrufroutine anzuzeigen, verwenden Sie !bugdumpComponent, wobei Component derselbe Parameter ist, der beim Registrieren dieser Routine an KeRegisterBugCheckCallback übergeben wurde.

Anzeigen sekundärer Rückrufdaten

Es gibt zwei Methoden zum Anzeigen sekundärer Rückrufdaten. Sie können den Befehl .enumtag verwenden oder Eine eigene Debuggererweiterung schreiben.

Jeder Block sekundärer Rückrufdaten wird durch ein GUID-Tag identifiziert. Dieses Tag wird durch das Guid-Feld des (KBUGCHECK_SECONDARY_DUMP_DATA)ReasonSpecificData-Parameters angegeben, der an BugCheckSecondaryDumpDataCallback übergeben wird.

Der Befehl .enumtag (Enumerate Secondary Callback Data) ist kein sehr präzises Instrument. Es zeigt jeden sekundären Datenblock an, der das -Tag und dann die Daten im Hexadezimal- und ASCII-Format anzeigt. Es ist im Allgemeinen nur nützlich, um zu bestimmen, welche Tags tatsächlich für sekundäre Datenblöcke verwendet werden.

Um diese Daten praktischer zu verwenden, empfiehlt es sich, eine eigene Debuggererweiterung zu schreiben. Diese Erweiterung muss Methoden in der Headerdatei dbgeng.h aufrufen. Ausführliche Informationen finden Sie unter Schreiben neuer Debuggererweiterungen.

Wenn Sie das GUID-Tag des sekundären Datenblocks kennen, sollte Ihre Erweiterung die Methode IDebugDataSpaces3::ReadTagged verwenden, um auf die Daten zuzugreifen. Der Prototyp ist wie folgt:

STDMETHOD(ReadTagged)(
    THIS_
    IN LPGUID Tag,
    IN ULONG Offset,
    OUT OPTIONAL PVOID Buffer,
    IN ULONG BufferSize,
    OUT OPTIONAL PULONG TotalSize
    ) PURE; 

Hier sehen Sie ein Beispiel für die Verwendung dieser Methode:

UCHAR RawData[MY_DATA_SIZE];
GUID MyGuid = .... ;

Success = DataSpaces->ReadTagged(  &MyGuid,  0,  RawData,
                                   sizeof(RawData),  NULL); 

Wenn Sie eine BufferSize-Größe angeben, die zu klein ist, wird ReadTagged erfolgreich ausgeführt, schreibt jedoch nur die angeforderte Anzahl von Bytes in Buffer. Wenn Sie eine PufferSize angeben, die zu groß ist, wird ReadTagged erfolgreich, schreibt jedoch nur die tatsächliche Blockgröße in Buffer. Wenn Sie einen Zeiger für TotalSize angeben, verwendet ReadTagged ihn, um die Größe des tatsächlichen Blocks zurückzugeben. Wenn auf den Block nicht zugegriffen werden kann, gibt ReadTagged einen Fehler status Code zurück.

Wenn zwei Blöcke identische GUID-Tags aufweisen, wird der erste übereinstimmende Block zurückgegeben, und auf den zweiten Block kann nicht zugegriffen werden.

Wenn Sie sich des GUID-Tags Ihres Blocks nicht sicher sind, können Sie die Methoden IDebugDataSpaces3::StartEnumTagged, IDebugDataSpaces3::GetNextTagged und IDebugDataSpaces3::EndEnumTagged verwenden, um die markierten Blöcke aufzulisten. Ihre Prototypen sind wie folgt:

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;

Debuggen von Rückrufroutinen

Es ist auch möglich, die Rückrufroutine selbst zu debuggen. Haltepunkte innerhalb von Rückrufroutinen funktionieren genauso wie jeder andere Haltepunkt.

Wenn die Rückrufroutine eine zweite Fehlerüberprüfung verursacht, wird diese neue Fehlerprüfung zuerst verarbeitet. Windows wiederholt jedoch bestimmte Teile des Prozesses "Beenden" nicht, z. B. schreibt es keine zweite Absturzabbilddatei. Der auf dem blauen Bildschirm angezeigte Stoppcode ist der zweite Fehlerüberprüfungscode. Wenn ein Kerneldebugger angefügt ist, werden normalerweise Meldungen zu beiden Fehlerüberprüfungen angezeigt.