Debuggen von Ereignissen
Ein Debugereignis ist ein Vorfall beim Debuggen, der dazu führt, dass das System den Debugger benachrichtigt. Zu den Debugereignissen gehören das Erstellen eines Prozesses, das Erstellen eines Threads, das Laden einer DLL (Dynamic Link Library), das Entladen einer DLL, das Senden einer Ausgabezeichenfolge und das Generieren einer Ausnahme.
Wenn ein Debugereignis auftritt, während ein Debugger auf einen Debugger wartet, füllt das System die durch WaitForDebugEvent angegebene DEBUG_EVENT Struktur mit Informationen zur Beschreibung des Ereignisses aus.
Wenn das System den Debugger eines Debuggingereignisses benachrichtigt, hält es auch alle Threads im betroffenen Prozess an. Die Ausführung der Threads wird erst fortgesetzt, wenn der Debugger das Debugereignis mithilfe von ContinueDebugEventfortsetzt. Die folgenden Debugereignisse können auftreten, während ein Prozess gedebuggt wird.
Debuggingereignis | Beschreibung |
---|---|
CREATE_PROCESS_DEBUG_EVENT |
Wird generiert, wenn ein neuer Prozess in einem Prozess erstellt wird, der gedebuggt wird oder wenn der Debugger mit dem Debuggen eines bereits aktiven Prozesses beginnt. Das System generiert dieses Debugereignis, bevor der Prozess im Benutzermodus ausgeführt wird und bevor das System andere Debugereignisse für den neuen Prozess generiert. Die DEBUG_EVENT-Struktur enthält eine CREATE_PROCESS_DEBUG_INFO Struktur. Diese Struktur enthält ein Handle für den neuen Prozess, ein Handle für die Bilddatei des Prozesses, ein Handle für den anfänglichen Thread des Prozesses und andere Informationen, die den neuen Prozess beschreiben. Der Handle für den Prozess hat PROCESS_VM_READ und PROCESS_VM_WRITE Zugriff. Wenn ein Debugger über diese Arten von Zugriff auf einen Thread verfügt, kann er mithilfe der ReadProcessMemory- und WriteProcessMemory--Funktionen in den Arbeitsspeicher des Prozesses lesen und schreiben. Wenn das System zuvor ein EXIT_PROCESS_DEBUG_EVENT-Ereignis gemeldet hat, schließt das System dieses Handle, wenn der Debugger die ContinueDebugEvent-Funktion aufruft. Das Handle für die Bilddatei des Prozesses hat GENERIC_READ Zugriff und wird für die Lesefreigabe geöffnet. Der Debugger sollte diesen Handle schließen, während CREATE_PROCESS_DEBUG_EVENT verarbeitet wird. Der Handle für den anfänglichen Thread des Prozesses verfügt über THREAD_GET_CONTEXT, THREAD_SET_CONTEXT und THREAD_SUSPEND_RESUME Zugriff auf den Thread. Wenn ein Debugger über diese Arten von Zugriff auf einen Thread verfügt, kann er mithilfe der GetThreadContext- und SetThreadContext- Funktionen lesen und in die Register des Threads schreiben und in die Register des Threads schreiben und anhalten und fortsetzen, indem die funktionen SuspendThread und ResumeThread- verwendet werden. Wenn das System zuvor ein EXIT_PROCESS_DEBUG_EVENT-Ereignis gemeldet hat, schließt das System dieses Handle, wenn der Debugger die ContinueDebugEvent-Funktion aufruft. |
CREATE_THREAD_DEBUG_EVENT |
Wird generiert, wenn ein neuer Thread in einem Prozess erstellt wird, der gedebuggt wird oder wenn der Debugger mit dem Debuggen eines bereits aktiven Prozesses beginnt. Dieses Debugereignis wird generiert, bevor der neue Thread im Benutzermodus ausgeführt wird. Die DEBUG_EVENT-Struktur enthält eine CREATE_THREAD_DEBUG_INFO Struktur. Diese Struktur enthält ein Handle für den neuen Thread und die Startadresse des Threads. Der Handle verfügt über THREAD_GET_CONTEXT, THREAD_SET_CONTEXT und THREAD_SUSPEND_RESUME Zugriff auf den Thread. Wenn ein Debugger über diese Arten von Zugriff auf einen Thread verfügt, kann er mithilfe der GetThreadContext- und SetThreadContext- Funktionen lesen und in die Register des Threads schreiben und in die Register des Threads schreiben und anhalten und fortsetzen, indem die funktionen SuspendThread und ResumeThread- verwendet werden. Wenn das System zuvor ein EXIT_THREAD_DEBUG_EVENT-Ereignis gemeldet hat, schließt das System das Handle an den neuen Thread, wenn der Debugger die ContinueDebugEvent--Funktion aufruft. |
EXCEPTION_DEBUG_EVENT |
Wird generiert, wenn beim Debuggen eine Ausnahme auftritt. Mögliche Ausnahmen sind der Versuch, auf nicht zugänglichen Speicher zuzugreifen, Haltepunktanweisungen auszuführen, versuchen, durch Null zu dividieren, oder eine andere Ausnahme, die in strukturierte Ausnahmebehandlungangegeben ist. Die DEBUG_EVENT-Struktur enthält eine EXCEPTION_DEBUG_INFO Struktur. Diese Struktur beschreibt die Ausnahme, die das Debuggingereignis verursacht hat. Neben den Standard-Ausnahmebedingungen kann während des Debuggens des Konsolenprozesses ein zusätzlicher Ausnahmecode auftreten. Das System generiert einen DBG_CONTROL_C Ausnahmecode, wenn STRG+C in einen Konsolenprozess eingegeben wird, der STRG+C-Signale verarbeitet und gedebuggt wird. Dieser Ausnahmecode soll nicht von Anwendungen behandelt werden. Eine Anwendung sollte niemals einen Ausnahmehandler verwenden, um ihn zu behandeln. Sie wird nur für den Vorteil des Debuggers ausgelöst und wird nur verwendet, wenn ein Debugger an den Konsolenprozess angefügt wird. Wenn ein Prozess nicht gedebuggt wird oder wenn der Debugger die DBG_CONTROL_C Ausnahme nicht behandelt (über den gn-Befehl) übergibt, wird die Liste der Handlerfunktionen der Anwendung durchsucht, wie für die SetConsoleCtrlHandler-Funktion dokumentiert. Wenn der Debugger die DBG_CONTROL_C Ausnahme (über den Befehl "gh") behandelt, wird von einer Anwendung die STRG+C-Ausnahme nicht bemerkt, mit Ausnahme von Code wie diesem. while ((inputChar = getchar()) != EOF) ... Daher kann der Debugger nicht verwendet werden, um das Warten des Lesevorgangs in einem solchen Code zu beenden. |
EXIT_PROCESS_DEBUG_EVENT |
Wird generiert, wenn der letzte Thread in einem Prozess, der gedebuggt wird, beendet wird. Dieses Debugereignis tritt unmittelbar nach dem Entladen der DLLs des Prozesses auf und aktualisiert den Beendigungscode des Prozesses. Die DEBUG_EVENT-Struktur enthält eine EXIT_PROCESS_DEBUG_INFO Struktur, die den Ausgangscode angibt. Der Debugger behandelt alle internen Strukturen, die dem Prozess zugeordnet sind, nach Eingang dieses Debugereignisses. Das System schließt das Handle des Debuggers mit dem beendenden Prozess und allen Threads des Prozesses. Der Debugger sollte diese Handles nicht schließen. Der Kernelmodusteil des Prozess herunterfahrens kann erst abgeschlossen werden, wenn der Debugger, der dieses Ereignis empfängt, ContinueDebugEvent-aufgerufen wird. Bis dahin sind die Prozesshandles geöffnet, und der virtuelle Adressraum wird nicht freigegeben, sodass der Debugger den untergeordneten Prozess untersuchen kann. Um Benachrichtigungen zu erhalten, wenn der Kernelmodusteil des Prozess heruntergefahren ist, duplizieren Sie das mit CREATE_PROCESS_DEBUG_EVENT zurückgegebene Handle, rufen Sie ContinueDebugEventauf, und warten Sie dann, bis das duplizierte Prozesshandle signalisiert wird. |
EXIT_THREAD_DEBUG_EVENT |
Wird generiert, wenn ein Thread, der Teil eines Prozesses ist, der debugged beendet wird. Das System generiert dieses Debugereignis unmittelbar nach der Aktualisierung des Beendigungscodes des Threads. Die DEBUG_EVENT-Struktur enthält eine EXIT_THREAD_DEBUG_INFO Struktur, die den Ausgangscode angibt. Dieses Debugereignis tritt nicht auf, wenn der beendende Thread der letzte Thread eines Prozesses ist. In diesem Fall tritt stattdessen das EXIT_PROCESS_DEBUG_EVENT Debugereignis auf. Der Debugger behandelt alle internen Strukturen, die dem Thread zugeordnet sind, nach Erhalt dieses Debugereignisses. Das System schließt den Handle des Debuggers mit dem beendenden Thread. Dieser Handle sollte vom Debugger nicht geschlossen werden. |
LOAD_DLL_DEBUG_EVENT |
Wird generiert, wenn ein prozess, der gedebuggt wird, eine DLL lädt. Dieses Debugereignis tritt auf, wenn das Systemladeprogramm Verknüpfungen zu einer DLL auflösen oder wenn der debuggierte Prozess die LoadLibrary--Funktion verwendet. Dieses Debugereignis tritt nur auf, wenn das System eine DLL zum ersten Mal an den virtuellen Adressraum eines Prozesses anfügt. Die DEBUG_EVENT-Struktur enthält eine LOAD_DLL_DEBUG_INFO Struktur. Diese Struktur enthält ein Handle für die neu geladene DLL, die Basisadresse der DLL und andere Informationen, die die DLL beschreiben. Der Debugger sollte das Handle beim Verarbeiten LOAD_DLL_DEBUG_EVENT schließen. In der Regel lädt ein Debugger eine Symboltabelle, die der DLL zugeordnet ist, wenn dieses Debugereignis angezeigt wird. |
OUTPUT_DEBUG_STRING_EVENT |
Generiert, wenn ein prozess, der gedebuggt wird, verwendet die OutputDebugString Funktion. Die DEBUG_EVENT-Struktur enthält eine OUTPUT_DEBUG_STRING_INFO Struktur. Diese Struktur gibt die Adresse, Länge und das Format der Debugzeichenfolge an. |
UNLOAD_DLL_DEBUG_EVENT |
Wird generiert, wenn ein Prozess, der gedebuggt wird, eine DLL mithilfe der FreeLibrary-Funktion entladen. Dieses Debugereignis tritt nur auf, wenn eine DLL zuletzt aus dem Adressraum eines Prozesses entladen wird (d. a. wenn die Anzahl der DLL-Verwendungen null ist). Die DEBUG_EVENT-Struktur enthält eine UNLOAD_DLL_DEBUG_INFO Struktur. Diese Struktur gibt die Basisadresse der DLL im Adressraum des Prozesses an, der die DLL entlädt. In der Regel entlädt ein Debugger eine Symboltabelle, die der DLL zugeordnet ist, sobald dieses Debugereignis empfangen wird. Wenn ein Prozess beendet wird, entlädt das System automatisch die DLLs des Prozesses, generiert jedoch kein UNLOAD_DLL_DEBUG_EVENT Debugereignis. |
RIP_EVENT |
Wird generiert, wenn ein prozess, der gedebuggt wird, außerhalb des Steuerelements des Systemdebuggers. Die DEBUG_EVENT-Struktur enthält eine RIP_INFO Struktur. Diese Struktur gibt den Fehler und den Typ des Fehlers an. |