Verwenden der Erweiterung !analyze
Der erste Schritt beim Debuggen eines abgestürzten Zielcomputers oder einer abgestürzten Anwendung besteht darin, den Erweiterungsbefehl "!analysieren " zu verwenden. Diese Erweiterung führt eine große Menge automatisierter Analysen durch. Die Ergebnisse dieser Analyse werden im Fenster "Debuggerbefehl" angezeigt.
Sie sollten die Option "-v " für eine ausführliche Anzeige von Daten verwenden. Weitere Informationen zu anderen Optionen finden Sie auf der Referenzseite "!analyze ".
Beispiel für einen Benutzermodus !analyze -v
In diesem Beispiel wird der Debugger an eine Benutzermodusanwendung angefügt, die eine Ausnahme festgestellt hat.
0:000> !analyze -v
*******************************************************************************
* *
* Exception Analysis *
* *
*******************************************************************************
Debugger SolutionDb Connection::Open failed 80004005
Wenn Sie mit dem Internet verbunden sind, versucht der Debugger, auf eine Datenbank mit Absturzlösungen zuzugreifen, die von Microsoft verwaltet werden. In diesem Fall wurde eine Fehlermeldung angezeigt, die angibt, dass Ihr Computer nicht auf das Internet zugreifen konnte oder die Website nicht funktionierte.
FAULTING_IP:
ntdll!PropertyLengthAsVariant+73
77f97704 cc int 3
Das feld FAULTING_IP zeigt den Anweisungszeiger zum Zeitpunkt des Fehlers an.
EXCEPTION_RECORD: ffffffff -- (.exr ffffffffffffffff)
ExceptionAddress: 77f97704 (ntdll!PropertyLengthAsVariant+0x00000073)
ExceptionCode: 80000003 (Break instruction exception)
ExceptionFlags: 00000000
NumberParameters: 3
Parameter[0]: 00000000
Parameter[1]: 00010101
Parameter[2]: ffffffff
Das Feld EXCEPTION_RECORD zeigt den Ausnahmedatensatz für diesen Absturz an. Diese Informationen können auch mithilfe des Befehls ".exr" (Ausnahmedatensatz anzeigen) angezeigt werden.
BUGCHECK_STR: 80000003
Das feld BUGCHECK_STR zeigt den Ausnahmecode an. Der Name ist ein Falschnomer – die Überprüfung des Ausdrucksfehlers bedeutet tatsächlich einen Kernelmodusabsturz. Im Benutzermodusdebugging wird der Ausnahmecode angezeigt– in diesem Fall 0x80000003.
DEFAULT_BUCKET_ID: APPLICATION_FAULT
Das Feld "DEFAULT_BUCKET_ID" zeigt die allgemeine Kategorie von Fehlern an, zu denen dieser Fehler gehört.
PROCESS_NAME: MyApp.exe
Das feld PROCESS_NAME gibt den Namen des Prozesses an, der die Ausnahme ausgelöst hat.
LAST_CONTROL_TRANSFER: from 01050963 to 77f97704
Im Feld LAST_CONTROL_TRANSFER wird der letzte Aufruf des Stapels angezeigt. In diesem Fall 0x01050963 der Code bei 0x77F97704 als Funktion bezeichnet. Sie können diese Adressen mit dem Befehl ln (List Nearest Symbols) verwenden, um zu bestimmen, in welchen Modulen und Funktionen sich diese Adressen befinden.
STACK_TEXT:
0006b9dc 01050963 00000000 0006ba04 000603fd ntdll!PropertyLengthAsVariant+0x73
0006b9f0 010509af 00000002 0006ba04 77e1a449 MyApp!FatalErrorBox+0x55 [D:\source_files\MyApp\util.c @ 541]
0006da04 01029f4e 01069850 0000034f 01069828 MyApp!ShowAssert+0x47 [D:\source_files\MyApp\util.c @ 579]
0006db6c 010590c3 000e01ea 0006fee4 0006feec MyApp!SelectColor+0x103 [D:\source_files\MyApp\colors.c @ 849]
0006fe04 77e11d0a 000e01ea 00000111 0000413c MyApp!MainWndProc+0x1322 [D:\source_files\MyApp\MyApp.c @ 1031]
0006fe24 77e11bc8 01057da1 000e01ea 00000111 USER32!UserCallWinProc+0x18
0006feb0 77e172b4 0006fee4 00000001 010518bf USER32!DispatchMessageWorker+0x2d0
0006febc 010518bf 0006fee4 00000000 01057c5d USER32!DispatchMessageA+0xb
0006fec8 01057c5d 0006fee4 77f82b95 77f83920 MyApp!ProcessQCQPMessage+0x3b [D:\source_files\MyApp\util.c @ 2212]
0006ff70 01062cbf 00000001 00683ed8 00682b88 MyApp!main+0x1e6 [D:\source_files\MyApp\MyApp.c @ 263]
0006ffc0 77e9ca90 77f82b95 77f83920 7ffdf000 MyApp!mainCRTStartup+0xff [D:\source_files\MyApp\crtexe.c @ 338]
0006fff0 00000000 01062bc0 00000000 000000c8 KERNEL32!BaseProcessStart+0x3d
Das Feld STACK_TEXT zeigt eine Stapelablaufverfolgung der fehlerhaften Komponente an.
FOLLOWUP_IP:
MyApp!FatalErrorBox+55
01050963 5e pop esi
FOLLOWUP_NAME: dbg
SYMBOL_NAME: MyApp!FatalErrorBox+55
MODULE_NAME: MyApp
IMAGE_NAME: MyApp.exe
DEBUG_FLR_IMAGE_TIMESTAMP: 383490a9
Wenn !analyze die Anweisung bestimmt, die wahrscheinlich den Fehler verursacht hat, wird sie im Feld FOLLOWUP_IP angezeigt. In den Feldern SYMBOL_NAME, MODULE_NAME, IMAGE_NAME und DEBUG_FLR_IMAGE_TIMESTAMP werden das Symbol, modul, der Bildname und der Bildzeitstempel angezeigt, der dieser Anweisung entspricht.
STACK_COMMAND: .ecxr ; kb
Das feld STACK_COMMAND zeigt den Befehl an, der zum Abrufen des STACK_TEXT verwendet wurde. Sie können diesen Befehl verwenden, um diese Stapelablaufverfolgungsanzeige zu wiederholen oder sie so zu ändern, dass verwandte Stapelinformationen erhalten werden.
BUCKET_ID: 80000003_MyApp!FatalErrorBox+55
Das Feld BUCKET_ID zeigt die spezifische Kategorie von Fehlern an, zu denen der aktuelle Fehler gehört. Diese Kategorie hilft dem Debugger zu bestimmen, welche anderen Informationen in der Analyseausgabe angezeigt werden sollen.
Followup: dbg
---------
Informationen zu den FOLLOWUP_NAME und den Nachverfolgungsfeldern finden Sie unter "Followup Field" und "triage.ini Datei".
Es gibt eine Vielzahl anderer Felder, die angezeigt werden können:
Wenn das Steuerelement an eine ungültige Adresse übertragen wurde, enthält das Feld FAULTING_IP diese ungültige Adresse. Anstelle des felds FOLLOWUP_IP zeigt das Feld FAILED_INSTRUCTION_ADDRESS den zerlegten Code aus dieser Adresse an, obwohl diese Demontage wahrscheinlich bedeutungslos sein wird. In dieser Situation beziehen sich die Felder SYMBOL_NAME, MODULE_NAME, IMAGE_NAME und DEBUG_FLR_IMAGE_TIMESTAMP auf den Aufrufer dieser Anweisung.
Wenn der Prozessor falsch ausgeht, werden möglicherweise die Felder SINGLE_BIT_ERROR, TWO_BIT_ERROR oder POSSIBLE_INVALID_CONTROL_TRANSFER angezeigt.
Wenn Arbeitsspeicherbeschädigungen aufgetreten sind, gibt das Feld CHKIMG_EXTENSION den Erweiterungsbefehl "!chkimg " an, der zur Untersuchung verwendet werden soll.
Ein Kernelmodus !analyze -v Beispiel
In diesem Beispiel wird der Debugger an einen Computer angefügt, der gerade abgestürzt ist.
kd> !analyze -v
*******************************************************************************
* *
* Bugcheck Analysis *
* *
*******************************************************************************
DRIVER_IRQL_NOT_LESS_OR_EQUAL (d1)
An attempt was made to access a pagable (or completely invalid) address at an
interrupt request level (IRQL) that is too high. This is usually
caused by drivers using improper addresses.
If kernel debugger is available get stack backtrace.
Das erste Element der Anzeige zeigt den Fehlerüberprüfungscode und Informationen zu dieser Art von Fehlerüberprüfung an. Einige des angezeigten Texts gelten möglicherweise nicht für diese bestimmte Instanz. Weitere Informationen zu den einzelnen Fehlerüberprüfungen finden Sie im Abschnitt "Codereferenz zur Fehlerüberprüfung".
Arguments:
Arg1: 00000004, memory referenced
Arg2: 00000002, IRQL
Arg3: 00000001, value 0 = read operation, 1 = write operation
Arg4: f832035c, address which referenced memory
Die Fehlerüberprüfungsparameter werden als Nächstes angezeigt. Sie folgen jeweils einer Beschreibung. Der dritte Parameter ist z. B. 1, und im folgenden Kommentar wird erläutert, dass dies angibt, dass ein Schreibvorgang fehlgeschlagen ist.
## Debugging Details:
WRITE_ADDRESS: 00000004 Nonpaged pool
CURRENT_IRQL: 2
Die nächsten Felder variieren je nach Art des Absturzes. In diesem Fall werden WRITE_ADDRESS- und CURRENT_IRQL felder angezeigt. Dies sind lediglich die Informationen, die in den Fehlerüberprüfungsparametern angezeigt werden. Durch den Vergleich der Anweisung "Nonpaged pool" mit dem Fehlerüberprüfungstext, der "versucht wurde, auf eine auslagerungsfähige (oder vollständig ungültige) Adresse zuzugreifen" liest, können wir sehen, dass die Adresse ungültig war. Die ungültige Adresse in diesem Fall war 0x00000004.
FAULTING_IP:
USBPORT!USBPORT_BadRequestFlush+7c
f832035c 894204 mov [edx+0x4],eax
Das feld FAULTING_IP zeigt den Anweisungszeiger zum Zeitpunkt des Fehlers an.
DEFAULT_BUCKET_ID: DRIVER_FAULT
Das Feld "DEFAULT_BUCKET_ID" zeigt die allgemeine Kategorie von Fehlern an, zu denen dieser Fehler gehört.
BUGCHECK_STR: 0xD1
Das Feld BUGCHECK_STR zeigt den Fehlerprüfcode an, den wir bereits gesehen haben. In einigen Fällen werden zusätzliche Triageinformationen angefügt.
TRAP_FRAME: f8950dfc -- (.trap fffffffff8950dfc)
.trap fffffffff8950dfc
ErrCode = 00000002
eax=81cc86dc ebx=81cc80e0 ecx=81e55688 edx=00000000 esi=81cc8028 edi=8052cf3c
eip=f832035c esp=f8950e70 ebp=f8950e90 iopl=0 nv up ei pl nz ac po nc
cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00010216
USBPORT!USBPORT_BadRequestFlush+7c:
f832035c 894204 mov [edx+0x4],eax ds:0023:00000004=????????
.trap
Resetting default context
Das Feld TRAP_FRAME zeigt den Trapframe für diesen Absturz an. Diese Informationen können auch mithilfe des BEFEHLS TRAP (Display Trap Frame) angezeigt werden.
LAST_CONTROL_TRANSFER: from f83206e0 to f832035c
Im Feld LAST_CONTROL_TRANSFER wird der letzte Aufruf des Stapels angezeigt. In diesem Fall 0xF83206E0 der Code bei 0xF832035C als Funktion bezeichnet. Sie können den Befehl "ln" (Listennächste Symbole) verwenden, um zu bestimmen, in welchem Modul und welche Funktion sich diese Adressen befinden.
STACK_TEXT:
f8950e90 f83206e0 024c7262 00000000 f8950edc USBPORT!USBPORT_BadRequestFlush+0x7c
f8950eb0 804f5561 81cc8644 81cc8028 6d9a2f30 USBPORT!USBPORT_DM_TimerDpc+0x10c
f8950fb4 804f5644 6e4be98e 00000000 ffdff000 nt!KiTimerListExpire+0xf3
f8950fe0 8052c47c 8053cf20 00000000 00002e42 nt!KiTimerExpiration+0xb0
f8950ff4 8052c16a efdefd44 00000000 00000000 nt!KiRetireDpcList+0x31
Das Feld STACK_TEXT zeigt eine Stapelablaufverfolgung der fehlerhaften Komponente an.
FOLLOWUP_IP:
USBPORT!USBPORT_BadRequestFlush+7c
f832035c 894204 mov [edx+0x4],eax
Das Feld FOLLOWUP_IP zeigt die Demontage der Anweisung an, die wahrscheinlich den Fehler verursacht hat.
FOLLOWUP_NAME: usbtri
SYMBOL_NAME: USBPORT!USBPORT_BadRequestFlush+7c
MODULE_NAME: USBPORT
IMAGE_NAME: USBPORT.SYS
DEBUG_FLR_IMAGE_TIMESTAMP: 3b7d868b
In den Feldern SYMBOL_NAME, MODULE_NAME, IMAGE_NAME und DBG_FLR_IMAGE_TIMESTAMP werden das Symbol, das Modul, das Bild und der Bildzeitstempel angezeigt, der dieser Anweisung entspricht (sofern er gültig ist) oder dem Aufrufer dieser Anweisung (falls dies nicht der Fall ist).
STACK_COMMAND: .trap fffffffff8950dfc ; kb
Das feld STACK_COMMAND zeigt den Befehl an, der zum Abrufen des STACK_TEXT verwendet wurde. Sie können diesen Befehl verwenden, um diese Stapelablaufverfolgungsanzeige zu wiederholen oder sie so zu ändern, dass verwandte Stapelinformationen erhalten werden.
BUCKET_ID: 0xD1_W_USBPORT!USBPORT_BadRequestFlush+7c
Das Feld BUCKET_ID zeigt die spezifische Kategorie von Fehlern an, zu denen der aktuelle Fehler gehört. Diese Kategorie hilft dem Debugger zu bestimmen, welche anderen Informationen in der Analyseausgabe angezeigt werden sollen.
Informationen zu den FOLLOWUP_NAME und den Nachverfolgungsfeldern finden Sie unter "Followup Field" und "triage.ini Datei".
Es gibt eine Vielzahl anderer Felder, die angezeigt werden können:
Wenn das Steuerelement an eine ungültige Adresse übertragen wurde, enthält das Feld FAULTING_IP diese ungültige Adresse. Anstelle des felds FOLLOWUP_IP zeigt das Feld FAILED_INSTRUCTION_ADDRESS den zerlegten Code aus dieser Adresse an, obwohl diese Demontage wahrscheinlich bedeutungslos sein wird. In dieser Situation beziehen sich die Felder SYMBOL_NAME, MODULE_NAME, IMAGE_NAME und DBG_FLR_IMAGE_TIMESTAMP auf den Aufrufer dieser Anweisung.
Wenn der Prozessor falsch ausgeht, werden möglicherweise die Felder SINGLE_BIT_ERROR, TWO_BIT_ERROR oder POSSIBLE_INVALID_CONTROL_TRANSFER angezeigt.
Wenn Arbeitsspeicherbeschädigungen aufgetreten sind, gibt das Feld CHKIMG_EXTENSION den Erweiterungsbefehl "!chkimg " an, der zur Untersuchung verwendet werden soll.
Wenn im Code eines Gerätetreibers eine Fehlerüberprüfung aufgetreten ist, wird der Name möglicherweise im Feld BUGCHECKING_DRIVER angezeigt.
Das Nachverfolgungsfeld und die triage.ini-Datei
Im Benutzermodus und im Kernelmodus zeigt das Nachverfolgungsfeld in der Anzeige Informationen zum Besitzer des aktuellen Stapelframes an, falls dies bestimmt werden kann. Diese Informationen werden auf folgende Weise bestimmt:
Wenn die Erweiterung !analyze verwendet wird, beginnt der Debugger mit dem oberen Frame im Stapel und bestimmt, ob er für den Fehler verantwortlich ist. Wenn dies nicht der Grund ist, wird der nächste Frame analysiert. Dieser Vorgang wird fortgesetzt, bis ein Frame gefunden wird, der möglicherweise fehlerhaft ist.
Der Debugger versucht, den Besitzer des Moduls und der Funktion in diesem Frame zu ermitteln. Wenn der Besitzer bestimmt werden kann, gilt dieser Frame als fehlerhaft.
Wenn der Besitzer nicht bestimmt werden kann, übergibt der Debugger an den nächsten Stapelframe usw., bis der Besitzer bestimmt wird (oder der Stapel vollständig untersucht wird). Der erste Frame, dessen Besitzer in dieser Suche gefunden wird, gilt als fehlerhaft. Wenn der Stapel ohne gefundene Informationen erschöpft ist, wird kein Nachverfolgungsfeld angezeigt.
Der Besitzer des fehlerhaften Frames wird im Nachverfolgungsfeld angezeigt. Wenn !analyze -v verwendet wird, beziehen sich die Felder FOLLOWUP_IP, SYMBOL_NAME, MODULE_NAME, IMAGE_NAME und DBG_FLR_IMAGE_TIMESTAMP Felder auf diesen Frame.
Damit das Feld "Nachverfolgung" nützliche Informationen anzeigt, müssen Sie zunächst eine triage.ini Datei erstellen, die die Namen der Modul- und Funktionsbesitzer enthält.
Die datei triage.ini sollte die Besitzer aller Module identifizieren, die möglicherweise Fehler haben könnten. Sie können eine Informationszeichenfolge anstelle eines tatsächlichen Besitzers verwenden, diese Zeichenfolge darf jedoch keine Leerzeichen enthalten. Wenn Sie sicher sind, dass ein Modul nicht fehlerhaft ist, können Sie dieses Modul weglassen oder angeben, dass es übersprungen werden soll. Es ist auch möglich, Besitzer einzelner Funktionen anzugeben, wodurch der Triageprozess eine noch feinere Granularität erhält.
Ausführliche Informationen zur Syntax der triage.ini-Datei finden Sie unter Angeben von Modul- und Funktionsbesitzern.
Weitere !analyze-Techniken
Wenn kein Absturz oder eine Ausnahme aufgetreten ist, zeigt !analyze einen sehr kurzen Text an, der den aktuellen Status des Ziels angibt. In bestimmten Situationen können Sie erzwingen, dass die Analyse stattfindet, als wäre ein Absturz aufgetreten. Verwenden Sie !analyze -f , um diese Aufgabe auszuführen.
Wenn im Benutzermodus eine Ausnahme aufgetreten ist, Aber Sie glauben, dass das zugrunde liegende Problem ein hängendes Thread ist, legen Sie den aktuellen Thread auf den Thread fest, den Sie untersuchen, und verwenden Sie dann !analyze -hang. Diese Erweiterung führt eine Threadstapelanalyse durch, um festzustellen, ob Threads andere Threads blockieren.
Wenn im Kernelmodus eine Fehlerüberprüfung aufgetreten ist, aber Sie glauben, dass das zugrunde liegende Problem ein hängendes Thread ist, verwenden Sie !analyze -hang. Diese Erweiterung untersucht Sperren, die vom System gehalten werden, und scannt die DPC-Warteschlangenkette und zeigt alle Hinweise auf hängende Threads an. Wenn Sie glauben, dass das Problem ein Kernelmodusressourcen-Deadlock ist, verwenden Sie die Erweiterung !deadlock zusammen mit der Deadlock-Erkennungsoption "Driver Verifier".
Sie können bekannte Probleme auch automatisch ignorieren. Dazu müssen Sie zuerst eine XML-Datei erstellen, die eine formatierte Liste bekannter Probleme enthält. Verwenden Sie die Erweiterung !analyze -c -load KnownIssuesFile , um diese Datei zu laden. Wenn dann eine Ausnahme oder ein Unterbrechung auftritt, verwenden Sie die Erweiterung !analyze -c . Wenn die Ausnahme mit einem der bekannten Probleme übereinstimmt, wird die Ausführung des Ziels fortgesetzt. Wenn die Ausführung des Ziels nicht fortgesetzt wird, können Sie !analyze -v verwenden, um die Ursache des Problems zu ermitteln.
Weitere Informationen
Weitere Informationen finden Sie in diesen Themen.
Bug Check Code Reference (Referenz zu Fehlerüberprüfungscodes)