Share via


Aktivieren des Postmortemdebuggens

Ausnahmebehandlung im Benutzermodus

Ausnahmen und Haltepunkte

Die häufigsten Anwendungsfehler werden als Ausnahmen bezeichnet. Dazu gehören Zugriffsverletzungen, Division-by-Zero-Fehler, numerische Überläufe, CLR-Ausnahmen und viele andere Arten von Fehlern. Anwendungen können auch Breakpointunterbrechungen verursachen. Diese treten auf, wenn Windows die Anwendung nicht ausführen kann (z. B. wenn ein erforderliches Modul nicht geladen werden kann) oder wenn ein Haltepunkt gefunden wird. Haltepunkte können von einem Debugger in den Code eingefügt oder über eine Funktion wie DebugBreak aufgerufen werden.

Ausnahmehandlerrangfolge

Basierend auf Konfigurationswerten und den aktiven Debuggern behandelt Windows Benutzermodusfehler auf verschiedene Arten. Die folgende Sequenz zeigt die Rangfolge, die für die Fehlerbehandlung im Benutzermodus verwendet wird:

  1. Wenn derzeit ein Benutzermodusdebugger an den fehlerhaften Prozess angefügt ist, führen alle Fehler dazu, dass das Ziel in diesen Debugger einbricht.

    Solange der Benutzermodusdebugger angefügt ist, werden keine anderen Fehlerbehandlungsmethoden verwendet, auch wenn der Befehl gn (Go With Exception Not Handled) verwendet wird.

  2. Wenn kein Benutzermodusdebugger angefügt ist und der ausführende Code über eigene Ausnahmebehandlungsroutinen verfügt (z. B. try – außer), versucht diese Ausnahmebehandlungsroutine, den Fehler zu behandeln.

  3. Wenn kein Benutzermodusdebugger angefügt ist und Windows über eine offene Kerneldebuggingverbindung verfügt und der Fehler ein Breakpoint-Interrupt ist, versucht Windows, den Kerneldebugger zu kontaktieren.

    Kerneldebugverbindungen müssen während des Startvorgangs von Windows geöffnet werden. Wenn Sie verhindern möchten, dass ein Benutzermodus-Interrupt in den Kerneldebugger einbricht, können Sie das Hilfsprogramm KDbgCtrl mit dem Parameter -du verwenden. Ausführliche Informationen zum Konfigurieren von Kerneldebugverbindungen und zur Verwendung von KDbgCtrl finden Sie unter Getting Setup Up for Debugging.

    Im Kerneldebugger können Sie gh (Go With Exception Handled) verwenden, um den Fehler zu ignorieren und die Ausführung des Ziels fortzusetzen. Sie können gn (Go With Exception Not Handled) verwenden, um den Kerneldebugger zu umgehen und mit Schritt 4 fortzufahren.

  4. Wenn die Bedingungen in den Schritten 1, 2 und 3 nicht zutreffen, aktiviert Windows ein Debugtool, das in den Registrierungswerten von AeDebug konfiguriert ist. Jedes Programm kann im Voraus als Tool ausgewählt werden, das in dieser Situation verwendet werden kann. Das ausgewählte Programm wird als Postmortemdebugger bezeichnet.

  5. Wenn die Bedingungen in den Schritten 1, 2 und 3 nicht zutreffen und kein Postmortemdebugger registriert ist, zeigt Windows-Fehlerberichterstattung (WER) eine Meldung an und stellt Lösungen bereit, falls diese verfügbar sind. WER schreibt auch eine Speicherabbilddatei, wenn die entsprechenden Werte in der Registrierung festgelegt sind. Weitere Informationen finden Sie unter Verwenden von WER und Sammeln User-Mode Dumps.

DebugBreak-Funktion

Wenn ein postmortem-Debugger installiert wurde, können Sie den Debugger absichtlich von einer Benutzermodusanwendung aus unterbrechen, indem Sie die DebugBreak-Funktion aufrufen.

Angeben eines Postmortem-Debuggers

In diesem Abschnitt wird beschrieben, wie Tools wie WinDbg als postmortem-Debugger konfiguriert werden. Nach der Konfiguration wird der postmortem-Debugger automatisch gestartet, wenn eine Anwendung abstürzt.

Registrierungsschlüssel des Post Mortem-Debuggers

Windows-Fehlerberichterstattung (WER) erstellt den postmortem-Debuggerprozess unter Verwendung der im Registrierungsschlüssel AeDebug festgelegten Werte.

HKLM\Software\Microsoft\Windows NT\Currentversion\AeDebug

Es gibt zwei primäre Registrierungswerte von Interesse: Debugger und Auto. Der Debuggerregistrierungswert gibt die Befehlszeile für den postmortem-Debugger an. Der Wert für die Automatische Registrierung gibt an, ob der postmortem-Debugger automatisch gestartet wird oder ob zuerst ein Bestätigungsmeldungsfeld angezeigt wird.

Debugger (REG_SZ)

Dieser REG_SZ-Wert gibt den Debugger an, der das postmortale Debuggen verarbeitet.

Der vollständige Pfad zum Debugger muss aufgeführt werden, es sei denn, der Debugger befindet sich in einem Verzeichnis, das sich im Standardpfad befindet.

Die Befehlszeile wird aus der Debuggerzeichenfolge über einen Printf-Stilaufruf generiert, der drei Parameter enthält. Obwohl die Reihenfolge festgelegt ist, müssen keine oder alle verfügbaren Parameter verwendet werden.

DWORD (%ld): Prozess-ID des Zielprozesses.

DWORD (%ld): Ereignishandle, das in den postmortem Debuggerprozess dupliziert wird. Wenn der Postmortemdebugger das Ereignis signalisiert, wird der Zielprozess fortgesetzt, ohne darauf zu warten, dass der Postmortemdebugger beendet wird. Das Ereignis sollte nur signalisiert werden, wenn das Problem behoben wurde. Wenn der Postmortemdebugger beendet wird, ohne das Ereignis zu signalisieren, setzt WER die Sammlung von Informationen über die Zielprozesse fort.

void* (%p): Adresse einer JIT_DEBUG_INFO Struktur, die im Adressraum des Zielprozesses zugeordnet ist. Die -Struktur enthält zusätzliche Ausnahmeinformationen und den Kontext.

Auto (REG_SZ) Dieser REG_SZ Wert ist immer entweder 0 oder 1.

Wenn Auto auf 0 festgelegt ist, wird vor dem Starten des postmortalen Debugprozesses ein Bestätigungsmeldungsfeld angezeigt.

Wenn Auto auf 1 festgelegt ist, wird der postmortem-Debugger sofort erstellt.

Wenn Sie die Registrierung manuell bearbeiten, tun Sie dies sehr sorgfältig, da falsche Änderungen an der Registrierung möglicherweise das Starten von Windows nicht zulassen.

Beispiel für die Befehlszeilennutzung

Viele Postmortemdebugger verwenden eine Befehlszeile, die die Schalter -p und -e enthält, um anzugeben, dass die Parameter eine PID und ein Ereignis (bzw. ereignis) sind. Wenn Sie z. B. WinDbg über windbg.exe -I installieren, werden die folgenden Werte erstellt:

Debugger = "<Path>\WinDbg -p %ld -e %ld -g"
Auto = 1

Die Verwendung der WER %ld %ld %ld %p-Parameter ist flexibel. Beispiel: Es ist nicht erforderlich, um oder zwischen den WER-Parametern zu wechseln. Wenn Sie beispielsweise Windows Sysinternals ProcDump mit installieren procdump.exe -i , werden die folgenden Werte ohne Wechsel zwischen den WER%ld %ld %p-Parametern erstellt:

Debugger = "<Path>\procdump.exe" -accepteula -j "c:\Dumps" %ld %ld %p
Auto = 1

32- und 64-Bit-Debugger

Auf einer 64-Bit-Plattform werden die Registrierungswerte Debugger (REG_SZ) und Auto (REG_SZ) einzeln für 64-Bit- und 32-Bit-Anwendungen definiert. Ein zusätzlicher Windows-unter-Windows-Schlüssel (WOW) wird verwendet, um die Post-Mortem-Debugwerte der 32-Bit-Anwendung zu speichern.

HKLM\Software\Wow6432node\Microsoft\Windows NT\Currentversion\AeDebug

Verwenden Sie auf einer 64-Bit-Plattform einen 32-Bit-Post-Mortem-Debugger für 32-Bit-Prozesse und einen 64-Bit-Debugger für 64-Bit-Prozesse. Dadurch wird ein 64-Bit-Debugger vermieden, der sich in einem 32-Bit-Prozess auf die WOW64-Threads anstelle der 32-Bit-Threads konzentriert.

Bei vielen postmortem-Debuggern, einschließlich der Debugtools für Windows-Postmortemdebugger, wird der Installationsbefehl zweimal ausgeführt. einmal mit der x86-Version und einmal mit der x64-Version. Um z. B. WinDbg als interaktiven Postmortem-Debugger zu verwenden, wird der windbg.exe -I Befehl zweimal ausgeführt, einmal für jede Version.

64-Bit-Installation:

C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\windbg.exe –I

Dadurch wird der Registrierungsschlüssel mit diesen Werten aktualisiert.

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AeDebug
Debugger = "C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\windbg.exe" -p %ld -e %ld –g

32-Bit-Installation:

C:\Program Files (x86)\Windows Kits\10\Debuggers\x86\windbg.exe –I

Dadurch wird der Registrierungsschlüssel mit diesen Werten aktualisiert.

HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows NT\CurrentVersion\AeDebug
Debugger = "C:\Program Files (x86)\Windows Kits\10\Debuggers\x86\windbg.exe" -p %ld -e %ld –g

Konfigurieren von Post Mortem-Debuggern

Debugtools für Windows

Die Debugtools für Windows-Debugger unterstützen alle, als postmortem-Debugger festgelegt zu werden. Der Installationsbefehl beabsichtigt, dass der Prozess interaktiv debuggt wird.

WinDbg

Um den postmortem-Debugger auf WinDbg festzulegen, führen Sie aus windbg -I. (Die I muss groß geschrieben werden.) Dieser Befehl zeigt eine Erfolgs- oder Fehlermeldung an, nachdem er verwendet wurde. Um sowohl mit 32- als auch mit 64-Bit-Anwendungen zu arbeiten, führen Sie den Befehl für den 64- und den 32-Debugger aus.

C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\windbg.exe –I
C:\Program Files (x86)\Windows Kits\10\Debuggers\x86\windbg.exe –I

So wird der Registrierungseintrag AeDebug konfiguriert, wenn windbg -I ausgeführt wird.

Debugger = "<Path>\WinDbg -p %ld -e %ld -g"
Auto = 1

In den Beispielen ist Path> das Verzeichnis,< in dem sich der Debugger befindet.

Die Parameter -p und -e übergeben die Prozess-ID und das Ereignis, wie zuvor erläutert.

- g übergibt den Befehl g (Go) an WinDbg und setzt die Ausführung aus der aktuellen Anweisung fort.

Hinweis Es gibt ein erhebliches Problem beim Übergeben des Befehls g (Go). Das Problem bei diesem Ansatz besteht darin, dass Ausnahmen in der Regel aufgrund einer vorübergehenden Bedingung, die beim Neustart des Codes nicht mehr vorhanden ist, nicht immer wiederholt werden. Weitere Informationen zu diesem Problem finden Sie unter JDINFO (Verwenden von JIT_DEBUG_INFO).

Um dieses Problem zu vermeiden, verwenden Sie .jdinfo oder .dump /j. Dieser Ansatz ermöglicht es dem Debugger, sich im Kontext des relevanten Codefehlers zu befinden. Weitere Informationen finden Sie weiter unten in diesem Thema unter Just-In-Time-Debugging (JIT).

CDB

Um den postmortem Debugger auf CDB festzulegen, führen Sie cdb -iae (Install AeDebug) oder cdb -iaecKeyString (Install AeDebug with Command) aus.

C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\cdb.exe -iae
C:\Program Files (x86)\Windows Kits\10\Debuggers\x86\cdb.exe -iae

Wenn der Parameter -iaec verwendet wird, gibt KeyString eine Zeichenfolge an, die an das Ende der Befehlszeile angefügt werden soll, die zum Starten des postmortem-Debuggers verwendet wird. Wenn KeyString Leerzeichen enthält, muss es in Anführungszeichen eingeschlossen werden.

C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\cdb.exe -iaec [KeyString]
C:\Program Files (x86)\Windows Kits\10\Debuggers\x86\cdb.exe -iaec [KeyString]

Dieser Befehl zeigt nichts an, wenn er erfolgreich ist, und eine Fehlermeldung, wenn er fehlschlägt.

NTSD

Um den postmortem-Debugger auf NTSD festzulegen, führen Sie ntsd -iae (Install AeDebug) oder ntsd -iaecKeyString (Install AeDebug with Command) aus.

C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\ntsd.exe -iae
C:\Program Files (x86)\Windows Kits\10\Debuggers\x86\ntsd.exe -iae

Wenn der Parameter -iaec verwendet wird, gibt KeyString eine Zeichenfolge an, die an das Ende der Befehlszeile angefügt werden soll, die zum Starten des postmortem-Debuggers verwendet wird. Wenn KeyString Leerzeichen enthält, muss es in Anführungszeichen eingeschlossen werden.

C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\ntsd.exe -iaec [KeyString]
C:\Program Files (x86)\Windows Kits\10\Debuggers\x86\ntsd.exe -iaec [KeyString]

Dieser Befehl zeigt nichts an, wenn er erfolgreich ist, und ein Fehler in einem neuen Konsolenfenster, wenn ein Fehler auftritt.

Hinweis Da die Parameter -p %ld -e %ld -g immer zuerst in der Befehlszeile des postmortem-Debuggers angezeigt werden, sollten Sie den Parameter -iaec nicht verwenden, um den Parameter -server anzugeben, da -server nur dann funktioniert, wenn er zuerst in der Befehlszeile angezeigt wird. Um einen postmortem-Debugger zu installieren, der diesen Parameter enthält, müssen Sie die Registrierung manuell bearbeiten.

Visual Studio JIT-Debugger

Wenn Visual Studio installiert wurde, wird vsjitdebugger.exe als post mortem-Debugger registriert. Der Visual Studio-JIT-Debugger möchte den Prozess interaktiv debuggen.

Debugger = "C:\WINDOWS\system32\vsjitdebugger.exe" -p %ld -e %ld

Wenn Visual Studio aktualisiert oder neu installiert wird, wird dieser Eintrag neu geschrieben, und alle alternativen Werte werden überschrieben.

Window Sysinternals ProcDump

Das Windows Sysinternals ProcDump-Hilfsprogramm kann auch für die Postmortemabbilderfassung verwendet werden. Weitere Informationen zum Verwenden und Herunterladen von ProcDump finden Sie unter ProcDump.

Wie der WinDbg-Befehl .dump kann ProcDump ein Dump des Absturzes nicht interaktiv erfassen. Die Erfassung kann in jeder Windows-Systemsitzung erfolgen.

ProcDump wird beendet, wenn die Speicherabbilddateierfassung abgeschlossen ist, WER dann den Fehler meldet und der fehlerhafte Prozess beendet wird.

Verwenden Sie procdump -i zum Installieren von procdump und -you, um ProcDump sowohl für das 32- als auch für das 64-Bit-Post-Mortem-Debuggen zu deinstallieren.

<Path>\procdump.exe -i

Die Installations- und Deinstallationsbefehle geben die Registrierungswerte aus, die bei Erfolg geändert wurden, und die Fehler bei Einem Fehler.

Die ProcDump-Befehlszeilenoptionen in der Registrierung sind auf Folgendes festgelegt:

Debugger = <Path>\ProcDump.exe -accepteula -j "<DumpFolder>" %ld %ld %p

ProcDump verwendet alle drei Parameter – PID, Event und JIT_DEBUG_INFO. Weitere Informationen zum parameter JIT_DEBUG_INFO finden Sie weiter unten unter Just-In-Time-Debuggen (JIT).

Die Größe des erfassten Speicherabbilds lautet standardmäßig Mini (Prozess/Threads/Handles/Module/Adressraum), ohne dass eine Größenoption festgelegt ist, MiniPlus (Mini plus MEM_PRIVATE Pages) mit -mp set oder Full (all memory - entspricht ".dump /mA") mit -ma set.

Für Systeme mit ausreichendem Laufwerksspeicher wird eine vollständige Erfassung (-ma) empfohlen.

Verwenden Sie -ma mit der Option -i, um eine All Memory Capture-Instanz anzugeben. Geben Sie optional einen Pfad für die Speicherabbilddateien an.

<Path>\procdump.exe -ma -i c:\Dumps

Für Systeme mit begrenztem Laufwerksspeicher wird eine MiniPlus-Aufnahme (-mp) empfohlen.

<Path>\procdump.exe -mp -i c:\Dumps

Der Ordner, in dem die Speicherabbilddatei gespeichert werden soll, ist optional. Der Standardwert ist der aktuelle Ordner. Der Ordner sollte mit einer ACL gesichert werden, die gleich oder besser ist als die für C:\Windows\Temp verwendete. Weitere Informationen zum Verwalten der Sicherheit im Zusammenhang mit Ordnern finden Sie unter Sicherheit während des Postmortemdebuggens.

Um ProcDump als postmortem-Debugger zu deinstallieren und die vorherigen Einstellungen wiederherzustellen, verwenden Sie die Option -u (Deinstallieren).

<Path>\procdump.exe -u

Weitere Informationen zu ProcDump finden Sie unter ProcDump and Windows SysInternals Administrator's Reference von Mark Russinovich und Aaron Margosis veröffentlicht von Microsoft Press.

Just-in-Time-Debugging (JIT)

Festlegen des Kontexts auf die fehlerhafte Anwendung

Wie bereits erwähnt, ist es sehr wünschenswert, den Kontext mit dem Parameter JIT_DEBUG_INFO auf die Ausnahme festzulegen, die den Absturz verursacht hat. Weitere Informationen hierzu finden Sie unter .jdinfo (Use JIT_DEBUG_INFO).

Debuggingtools für Windows

In diesem Beispiel wird gezeigt, wie Sie die Registrierung bearbeiten, um einen anfänglichen Befehl (-c) auszuführen, der den Befehl .jdinfo <address> verwendet, um die zusätzlichen Ausnahmeinformationen anzuzeigen und den Kontext in den Speicherort der Ausnahme zu ändern (ähnlich wie .ecxr verwendet wird, legen Sie den Kontext auf den Ausnahmedatensatz fest).

Debugger = "<Path>\windbg.exe -p %ld -e %ld -c ".jdinfo 0x%p"
Auto = 1

Der %p-Parameter ist die Adresse einer JIT_DEBUG_INFO-Struktur im Adressraum des Zielprozesses. Der %p-Parameter wird mit 0x vorab angefügt, sodass er als Hexadezimwert interpretiert wird. Weitere Informationen finden Sie unter .jdinfo (Use JIT_DEBUG_INFO).

Um eine Mischung aus 32- und 64-Bit-Apps zu debuggen, konfigurieren Sie sowohl die 32- als auch die 64-Bit-Registrierungsschlüssel (oben beschrieben), und legen Sie den richtigen Pfad zum Speicherort der 64-Bit- und 32-Bit-WinDbg.exe fest.

Erstellen einer Speicherabbilddatei mithilfe von .dump

Verwenden Sie die .dump /j-Adresse<>, um eine Speicherabbilddatei zu erfassen, wenn ein Fehler auftritt, der die JIT_DEBUG_INFO Daten enthält.

<Path>\windbg.exe -p %ld -e %ld -c ".dump /j %p /u <DumpPath>\AeDebug.dmp; qd"

Verwenden Sie die Option /u, um einen eindeutigen Dateinamen zu generieren, damit mehrere Speicherabbilddateien automatisch erstellt werden können. Weitere Informationen zu den Optionen finden Sie unter .dump (Create Dump File).

Das erstellte Dump enthält die JITDEBUG_INFO Daten, die als Standardausnahmekontext gespeichert werden. Anstatt .jdinfo zum Anzeigen der Ausnahmeinformationen und zum Festlegen des Kontexts zu verwenden, verwenden Sie .exr -1, um den Ausnahmedatensatz anzuzeigen, und .ecxr, um den Kontext festzulegen. Weitere Informationen finden Sie unter .exr (Display Exception Record) und .ecxr (Display Exception Context Record).

Windows-Fehlerberichterstattung – q/qd

Die Art und Weise, wie die Debugsitzung endet, bestimmt, ob Windows-Fehlerberichterstattung den Fehler meldet.

Wenn die Debugsitzung vor dem Schließen des Debuggers mithilfe von qd getrennt wird, meldet WER den Fehler.

Wenn die Debugsitzung mit q beendet wird (oder wenn der Debugger ohne Trennen geschlossen wird), meldet WER den Fehler nicht.

Anfügen ; q oder ; qd bis zum Ende der Befehlszeichenfolge, um das gewünschte Verhalten aufzurufen.

Damit WER beispielsweise den Fehler melden kann, nachdem CDB ein Speicherabbild erfasst hat, konfigurieren Sie diese Befehlszeichenfolge.

<Path>\cdb.exe -p %ld -e %ld -c ".dump /j 0x%p /u c:\Dumps\AeDebug.dmp; qd"

In diesem Beispiel kann WER den Fehler melden, nachdem WinDbg ein Speicherabbild erfasst hat.

<Path>\windbg.exe -p %ld -e %ld -c ".dump /j %p /u <DumpPath>\AeDebug.dmp; qd""

Sicherheitsrisiken

Wenn Sie erwägen, das postmortale Debuggen auf einem Computer zu aktivieren, den Sie für andere Personen freigeben, lesen Sie Sicherheit während des postmortalen Debuggens.