Kontexte ändern

Beim Debuggen im Kernelmodus werden viele Prozesse, Threads und manchmal Benutzersitzungen gleichzeitig ausgeführt. Daher sind Ausdrücke wie "virtuelle Adresse 0x80002000" oder "das Eax-Register " mehrdeutig. Sie müssen den Kontext angeben, in dem solche Ausdrücke verstanden werden können.

Der Debugger verfügt über fünf verschiedene Kontexte, die Sie beim Debuggen festlegen können:

  1. Der Sitzungskontext gibt die Standardbenutzersitzung an.

  2. Der Prozesskontext bestimmt, wie der Debugger virtuelle Adressen interpretiert.

  3. Der Adresskontext des Benutzermodus wird fast nie direkt festgelegt. Dieser Kontext wird automatisch festgelegt, wenn Sie den Prozesskontext ändern.

  4. Der Registerkontext bestimmt, wie der Debugger Register interpretiert und auch die Ergebnisse einer Stapelablaufverfolgung steuert. Dieser Kontext wird auch als Threadkontext bezeichnet, obwohl dieser Begriff nicht vollständig genau ist. Ein expliziter Kontext ist auch ein Typ von Registerkontext. Wenn Sie einen expliziten Kontext angeben, wird dieser Kontext anstelle des aktuellen Registerkontexts verwendet.

  5. Der lokale Kontext bestimmt, wie der Debugger lokale Variablen interpretiert. Dieser Kontext wird auch als Bereich bezeichnet.

Sitzungskontext

Mehrere Anmeldesitzungen können gleichzeitig ausgeführt werden. Jede Anmeldesitzung verfügt über eigene Prozesse.

Die Erweiterung !session zeigt alle Anmeldesitzungen an oder ändert den aktuellen Sitzungskontext.

Der Sitzungskontext wird von den Erweiterungen !sprocess und !spoolused verwendet, wenn die Sitzungsnummer als "-2" eingegeben wird.

Wenn der Sitzungskontext geändert wird, wird der Prozesskontext automatisch in den aktiven Prozess für diese Sitzung geändert.

Prozesskontext

Jeder Prozess verfügt über ein eigenes Seitenverzeichnis, das aufzeichnet, wie virtuelle Adressen physischen Adressen zugeordnet werden. Wenn ein Thread innerhalb eines Prozesses ausgeführt wird, verwendet das Windows-Betriebssystem dieses Seitenverzeichnis, um virtuelle Adressen zu interpretieren.

Beim Debuggen im Benutzermodus bestimmt der aktuelle Prozess den Prozesskontext. Virtuelle Adressen, die in Debuggerbefehlen, Erweiterungen und Debuginformationsfenstern verwendet werden, werden mithilfe des Seitenverzeichnisses des aktuellen Prozesses interpretiert.

Beim Debuggen im Kernelmodus können Sie den Prozesskontext mithilfe des Befehls PROZESS (Prozesskontext festlegen) festlegen. Verwenden Sie diesen Befehl, um auszuwählen, welches Seitenverzeichnis des Prozesses zum Interpretieren virtueller Adressen verwendet wird. Nachdem Sie den Prozesskontext festgelegt haben, können Sie diesen Kontext in jedem Befehl verwenden, der Adressen annimmt. Sie können sogar Haltepunkte an dieser Adresse festlegen. Wenn Sie eine /i-Option in den .process-Befehl einschließen, um invasives Debuggen anzugeben, können Sie auch den Kerneldebugger verwenden, um Haltepunkte im Benutzerbereich festzulegen.

Sie können auch Haltepunkte im Benutzermodus über den Kerneldebugger festlegen, indem Sie einen prozessspezifischen Haltepunkt für eine Kernelraumfunktion verwenden. Legen Sie strategische Haltepunkte fest, und warten Sie, bis der entsprechende Kontext angezeigt wird.

Der Adresskontext im Benutzermodus ist Teil des Prozesskontexts. In der Regel müssen Sie den Adresskontext des Benutzermodus nicht direkt festlegen. Wenn Sie den Prozesskontext festlegen, ändert sich der Adresskontext im Benutzermodus automatisch in die Verzeichnisbasis der relevanten Seitentabelle für den Prozess.

Wenn Sie den Prozesskontext während des Debuggens im Kernelmodus festlegen, wird dieser Prozesskontext beibehalten, bis ein anderer PROZESS-Befehl den Kontext ändert. Der Adresskontext im Benutzermodus wird auch so lange beibehalten, bis er durch den Befehl ".process " oder ".context " geändert wird. Diese Kontexte werden nicht geändert, wenn der Zielcomputer ausgeführt wird, und sie werden nicht von Änderungen am Registerkontext oder dem lokalen Kontext beeinflusst.

Kontext registrieren

Jeder Thread verfügt über eigene Registerwerte. Diese Werte werden in den CPU-Registern gespeichert, wenn der Thread ausgeführt wird, und werden im Arbeitsspeicher gespeichert, wenn ein anderer Thread ausgeführt wird.

Beim Debuggen im Benutzermodus bestimmt der aktuelle Thread in der Regel den Registrierungskontext. Alle Verweise auf Register in Debuggerbefehlen, Erweiterungen und Debuginformationsfenstern werden entsprechend den Registern des aktuellen Threads interpretiert.

Sie können den Registrierungskontext in einen anderen Wert als den aktuellen Thread ändern, während Sie das Debuggen im Benutzermodus ausführen, indem Sie einen der folgenden Befehle verwenden:

CXR (Kontextdatensatz anzeigen)

ECXR (Ausnahmekontextdatensatz anzeigen)

Während des Debuggens im Kernelmodus können Sie den Registrierungskontext mithilfe einer Vielzahl von Debuggerbefehlen steuern, einschließlich der folgenden Befehle:

.thread (Festlegen des Registrierungskontexts)

CXR (Kontextdatensatz anzeigen)

.trap (Trap Frame anzeigen)

Diese Befehle ändern die Werte der CPU-Register nicht. Stattdessen ruft der Debugger den angegebenen Registerkontext aus seinem Speicherort im Arbeitsspeicher ab. Tatsächlich kann der Debugger nur die gespeicherten Registerwerte abrufen. (Andere Werte werden dynamisch festgelegt und nicht gespeichert. Die gespeicherten Werte reichen aus, um eine Stapelablaufverfolgung neu zu erstellen.

Nachdem der Registerkontext festgelegt wurde, wird der neue Registerkontext für alle Befehle verwendet, die Registerwerte verwenden, z. B. k (Display Stack Backtrace) und r (Registers)..

Beim Debuggen von Computern mit mehreren Prozessoren können Sie mit einigen Befehlen jedoch einen Prozessor angeben. (Weitere Informationen zu solchen Befehlen finden Sie unter Multiprozessorsyntax.) Wenn Sie einen Prozessor für einen Befehl angeben, verwendet der Befehl den Registerkontext des aktiven Threads auf dem angegebenen Prozessor anstelle des aktuellen Registerkontexts, auch wenn der angegebene Prozessor der aktuell aktive Prozessor ist.

Wenn der Registrierungskontext nicht mit der aktuellen Prozessormoduseinstellung übereinstimmt, erzeugen diese Befehle außerdem eine falsche oder bedeutungslose Ausgabe. Um die Ausgabefehler zu vermeiden, schlagen Befehle, die vom Registerstatus abhängen, fehl, bis Sie den Prozessormodus so ändern, dass er dem Registrierungskontext entspricht. Um den Prozessormodus zu ändern, verwenden Sie den Befehl EFFMACH (Effective Machine),

Das Ändern des Registerkontexts kann auch den lokalen Kontext ändern. Auf diese Weise kann der Registerkontext die Anzeige lokaler Variablen beeinflussen.

Wenn eine Anwendungsausführung, ein Schrittschritt oder eine Ablaufverfolgung erfolgt, wird der Registrierungskontext sofort zurückgesetzt, um der Position des Programmzählers zu entsprechen. Im Benutzermodus wird auch der Registrierungskontext zurückgesetzt, wenn der aktuelle Prozess oder Thread geändert wird.

Der Registerkontext wirkt sich auf Stapelablaufverfolgungen aus, da die Stapelablaufverfolgung an der Position beginnt, auf die der Stapelzeiger (insbesondere auf einem x86-basierten Prozessor) verweist. Wenn der Registerkontext auf einen ungültigen oder nicht zugänglichen Wert festgelegt ist, können Stapelablaufverfolgungen nicht abgerufen werden.

Sie können einen Prozessor breakpoint (Daten breakpoint) auf einen bestimmten Registerkontext anwenden, indem Sie den Befehl .apply_dbp (Datenhaltepunkt auf Kontext anwenden) verwenden.

Lokaler Kontext

Wenn ein Programm ausgeführt wird, hängt die Bedeutung lokaler Variablen vom Speicherort des Programmzählers ab, da sich der Bereich solcher Variablen nur auf die Funktion erstreckt, in der sie definiert sind.

Beim Debuggen im Benutzermodus oder Kernelmodus verwendet der Debugger den Bereich der aktuellen Funktion (den aktuellen Frame auf dem Stapel) als lokalen Kontext. Um diesen Kontext zu ändern, verwenden Sie den Befehl .frame (Lokalen Kontext festlegen), oder doppelklicken Sie im Fenster Aufrufe auf den gewünschten Frame.

Beim Debuggen im Benutzermodus ist der lokale Kontext immer ein Frame innerhalb der Stapelablaufverfolgung des aktuellen Threads. Beim Debuggen im Kernelmodus ist der lokale Kontext immer ein Frame innerhalb der Stapelablaufverfolgung des Threads des aktuellen Registerkontexts.

Sie können jeweils nur einen Stapelrahmen für den lokalen Kontext verwenden. Auf lokale Variablen in anderen Frames kann nicht zugegriffen werden.

Der lokale Kontext wird zurückgesetzt, wenn eines der folgenden Ereignisse auftritt:

  • Beliebige Programmausführung, Schrittschritte oder Ablaufverfolgung

  • Jede Verwendung des Threadtrennzeichens (~) in einem beliebigen Befehl

  • Jede Änderung des Registrierungskontexts

Mit der Erweiterung !for_each_frame können Sie einen einzelnen Befehl wiederholt ausführen, einmal für jeden Frame im Stapel. Dieser Befehl ändert den lokalen Kontext für jeden Frame, führt den angegebenen Befehl aus und gibt dann den lokalen Kontext auf seinen ursprünglichen Wert zurück.