Schritt-für-Schritt-Lab zum Debuggen von Windows-Treibern (Echo-Kernelmodus)
In diesem Lab wird der Kernel-Debugger WinDbg vorgestellt. Sie verwenden WinDbg zum Debuggen des Besipielcodes des Echo-Kernelmodus.
Ziele des Labs
Dieses Lab umfasst Übungen, die die Debugging-Werkzeuge vorstellen, gängige Debugging-Befehle lehren, die Verwendung von Haltepunkten veranschaulichen und zeigen, wie man die Debugging-Erweiterungen verwendet.
In dieser Übung verwenden Sie eine Live-Kernel-Debug-Verbindung, um die folgenden Aktionen zu untersuchen:
- Verwendung von Windows-Debugger-Befehlen
- Verwendung von Standardbefehlen (Aufruf von Stapeln, Variablen, Threads, IRQL)
- Verwendung erweiterter Treiber-Debugging-Befehle (!commands)
- Verwendung von Symbolen
- Setzen von Haltepunkten beim Live-Debugging
- Anzeigen von Aufrufstapeln
- Anzeigen der Plug-and-Play-Gerätestruktur
- Arbeiten mit Thread- und Prozesskontext
Debuggen im Benutzer- und Kernelmodus
Wenn Sie mit dem Windows-Debugger arbeiten, können Sie zwei Arten von Debugging durchführen:
Benutzermodus – Anwendungen und Subsysteme laufen auf dem Computer im Benutzermodus. Prozesse, die im Benutzermodus ausgeführt werden, tun dies innerhalb ihrer eigenen virtuellen Adressräume. Sie sind daran eingeschränkt, direkten Zugriff auf viele Teile des Systems zu erhalten, einschließlich Systemhardware, Arbeitsspeicher, der nicht für die Verwendung zugeordnet ist, und andere Teile des Systems, die die Systemintegrität beeinträchtigen könnten. Da Prozesse, die im Benutzermodus ausgeführt werden, effektiv vom System und anderen Benutzermodusprozessen isoliert sind, können sie diese Ressourcen nicht beeinträchtigen.
Kernelmodus – Das Betriebssystem und privilegierte Programme laufen im Kernelmodus. Der Code im Kernelmodus hat die Erlaubnis, auf jeden Teil des Systems zuzugreifen. Er ist nicht eingeschränkt wie der Code im Benutzermodus. Er kann sich Zugang zu jedem Teil eines anderen Prozesses verschaffen, der entweder im Benutzermodus oder im Kernelmodus läuft. Ein Großteil der Kernfunktionen des Betriebssystems und viele Hardwaregerätetreiber werden im Kernelmodus ausgeführt.
Diese Übung behandelt Debug-Befehle, die sowohl im Benutzermodus als auch im Kernelmodus häufig verwendet werden. Die Übung behandelt auch Debug-Erweiterungen, manchmal !commands genannt, die für das Debugging im Kernelmodus verwendet werden.
Setup der Übungsumgebung
Sie benötigen die folgende Hardware, um die Übung durchzuführen:
- Einen Laptop oder Desktop-Computer (Host) mit Windows 10
- Ein zweiter Laptop oder Desktop-Computer (Ziel) mit Windows 10
- Ein Netzwerk-Hub oder Router und Netzwerkkabel zur Verbindung der beiden Computer
- Zugang zum Internet, um Symboldateien herunterzuladen
Sie benötigen die folgende Software, um die Übung durchzuführen:
- Visual Studio
- Windows Software Development Kit (SDK) für Windows 10
- Windows Driver Kit (WDK) für Windows 10
- Der Beispiel-Echotreiber für Windows 10
Das Lab besteht aus den folgenden Abschnitten:
- Verbindung zu einer WinDbg-Sitzung im Kernelmodus
- Befehle und Techniken zur Fehlersuche im Kernelmodus
- Herunterladen und Erstellen des KMDF-Echo-Treibers
- Installieren Sie das Echo-Treiberbeispiel auf dem Zielsystem
- Verwenden von WinDbg, um Informationen über den Treiber anzuzeigen
- Anzeigen von Plug-and-Play-Gerätestrukturinformationen
- Arbeiten mit Haltepunkten und Quellcode
- Variablen und Aufrufstapel anzeigen
- Anzeigen von Prozessen und Threads
- IRQL, Register und Beendigung der WinDbg-Sitzung
- Ressourcen zum Debuggen unter Windows
Verbindung zu einer WinDbg-Sitzung im Kernelmodus
In diesem Abschnitt konfigurieren Sie das Netzwerk-Debugging auf dem Host und dem Zielsystem.
Die Computer in diesem Lab müssen so konfiguriert sein, dass sie eine Ethernet-Netzwerkverbindung für das Kernel-Debugging verwenden.
In diesem Lab werden zwei Computer verwendet. Der Windows-Debugger läuft auf dem Hostsystem und der Kernel Mode Driver Framework (KMDF) Echo-Treiber läuft auf dem Zielsystem.
Verwenden Sie einen Netzwerk-Hub oder -Router und Netzwerkkabel, um die beiden Computer zu verbinden.
Um mit Kernelmodus-Anwendungen zu arbeiten und WinDbg zu verwenden, empfehlen wir Ihnen, den KDNET-over-Ethernet-Transport zu verwenden. Informationen über die Verwendung des Ethernet-Transportprotokolls finden Sie unter Erste Schritte mit WinDbg (Kernelmodus). Weitere Informationen zum Einrichten des Zielcomputers finden Sie unter Vorbereiten eines Computers für die manuelle Treiberbereitstellung und Automatisches Einrichten des KDNET-Netzwerk-Kernel-Debugging.
Konfigurieren Sie das Kernelmodus-Debugging mit Hilfe des Ethernet
So aktivieren Sie das Kernelmodus-Debugging auf dem Zielsystem:
Öffnen Sie auf dem Hostsystem ein Eingabeaufforderungsfenster und geben Sie ipconfig ein, um seine IP-Adresse zu ermitteln.
Windows IP Configuration Ethernet adapter Ethernet: Connection-specific DNS Suffix . : Link-local IPv6 Address . . . . . : fe80::c8b6:db13:d1e8:b13b%3 Autoconfiguration IPv4 Address. . : 169.182.1.1 Subnet Mask . . . . . . . . . . . : 255.255.0.0 Default Gateway . . . . . . . . . :
Notieren Sie die IP-Adresse des Hostsystems: ______________________________________
Öffnen Sie auf dem Zielsystem ein Eingabeaufforderungsfenster und verwenden Sie den Befehl
ping
, um die Netzwerkkonnektivität zwischen den beiden Systemen zu bestätigen.ping 169.182.1.1
Verwenden Sie die tatsächliche IP-Adresse des Hostsystems, das Sie aufgezeichnet haben, anstelle von 169.182.1.1, die in der Beispielausgabe angezeigt wird.
Pinging 169.182.1.1 with 32 bytes of data: Reply from 169.182.1.1: bytes=32 time=1ms TTL=255 Reply from 169.182.1.1: bytes=32 time<1ms TTL=255 Reply from 169.182.1.1: bytes=32 time<1ms TTL=255 Reply from 169.182.1.1: bytes=32 time<1ms TTL=255 Ping statistics for 169.182.1.1: Packets: Sent = 4, Received = 4, Lost = 0 (0% loss), Approximate round trip times in milli-seconds: Minimum = 0ms, Maximum = 1ms, Average = 0ms
Aktivieren Sie das Kernelmodus-Debugging auf dem Zielsystem, indem Sie die folgenden Schritte ausführen.
Wichtig
Bevor Sie BCDEdit zum Ändern der Startinformationen verwenden, müssen Sie möglicherweise die Windows-Sicherheitsfunktionen wie BitLocker und Secure Boot auf dem Testcomputer vorübergehend aussetzen. Aktivieren Sie diese Sicherheitsfunktionen wieder, wenn die Tests abgeschlossen sind. Verwalten Sie den Testcomputer angemessen, wenn die Sicherheitsfunktionen deaktiviert sind. Secure Boot ist in UEFI normalerweise deaktiviert. Um auf die UEFI-Einstellungen zuzugreifen, verwenden Sie System, Recovery, Advanced start-up. Wählen Sie beim Neustart Fehlerbehebung, Erweiterte Optionen, UEFI-Firmware-Einstellungen. Seien Sie vorsichtig, da eine falsche Einstellung der UEFI-Optionen oder die Deaktivierung von BitLocker das System funktionsunfähig machen kann.
Öffnen Sie auf dem Zielcomputer ein Eingabeaufforderungsfenster als Administrator. Geben Sie diesen Befehl ein, um das Debugging zu aktivieren:
bcdedit /set {default} DEBUG YES
Geben Sie diesen Befehl ein, um die Testsignierung zu aktivieren:
bcdedit /set TESTSIGNING ON
Geben Sie diesen Befehl ein, um die IP-Adresse des Hostsystems festzulegen. Verwenden Sie die IP-Adresse des Hostsystems, die Sie zuvor aufgezeichnet haben, und nicht die angezeigte Adresse.
bcdedit /dbgsettings net hostip:192.168.1.1 port:50000 key:2steg4fzbj2sz.23418vzkd4ko3.1g34ou07z4pev.1sp3yo9yz874p
Warnung
Um die Sicherheit der Verbindung zu erhöhen und das Risiko zufälliger Verbindungsanfragen des Client-Debuggers zu verringern, verwenden Sie einen automatisch generierten Zufallsschlüssel. Weitere Informationen finden Sie unter Automatisches Einrichten des KDNET-Netzwerkkernen-Debuggings.
Geben Sie diesen Befehl ein, um zu überprüfen, ob die Werte für
dbgsettings
richtig eingestellt sind:bcdedit /dbgsettings
key 2steg4fzbj2sz.23418vzkd4ko3.1g34ou07z4pev.1sp3yo9yz874p debugtype NET hostip 169.168.1.1 port 50000 dhcp Yes The operation completed successfully.
Hinweis
Wenn Sie eine Meldung von der Firewall erhalten und den Debugger verwenden möchten, aktivieren Sie alle drei Kästchen.
Öffnen Sie auf dem Host-Computer ein Eingabeaufforderungsfenster als Administrator. In dieser Übung wird die x64-Version von WinDbg.exe aus dem Windows Driver Kit (WDK) verwendet, das als Teil der Windows-Kit-Installation installiert wurde. Wechseln Sie in das Standard-WinDbg-Verzeichnis, das unten abgebildet ist.
cd C:\Program Files(x86)\Windows Kits\10\Debuggers\x64
In diesen Übungen wird davon ausgegangen, dass auf beiden Computern eine 64-Bit-Version von Windows läuft, sowohl auf dem Ziel als auch auf dem Host. Wenn das nicht der Fall ist, ist es am besten, die gleichen bitness Tools auf dem Host laufen zu lassen, die auch auf dem Zielsystem laufen. Wenn das Ziel beispielsweise unter 32-Bit-Windows läuft, führen Sie eine 32-Bit-Version des Debuggers auf dem Host aus. Weitere Informationen finden Sie unter Auswahl der 32-Bit- oder 64-Bit-Debugging-Tools.
Öffnen Sie WinDbg mit Remote-Benutzer-Debug, indem Sie den folgenden Befehl verwenden. Die Werte für den Schlüssel und den Anschluss entsprechen den Werten, die Sie zuvor mit BCDEdit auf dem Zielcomputer festgelegt haben.
WinDbg –k net:port=50000,key=2steg4fzbj2sz.23418vzkd4ko3.1g34ou07z4pev.1sp3yo9yz874p
Starten Sie das Zielsystem neu.
In ein oder zwei Minuten sollte die Debug-Ausgabe auf dem Hostsystem angezeigt werden.
Microsoft (R) Windows Debugger Version 10.0.17074.1002 AMD64 Copyright (c) Microsoft Corporation. All rights reserved. Using NET for debugging Opened WinSock 2.0 Waiting to reconnect... Connected to target 169.182.1.1 on port 50005 on local IP 169.182.1.2 You can get the target MAC address by running .kdtargetmac command. Connected to Windows 10 16299 x64 target at (Wed Feb 28 17:16:23.051 2018 (UTC - 8:00)), ptr64 TRUE Kernel Debugger connection established. (Initial Breakpoint requested) Symbol search path is: srv* Executable search path is: Windows 10 Kernel Version 16299 MP (4 procs) Free x64 Product: WinNt, suite: TerminalServer SingleUserTS Built by: 16299.15.amd64fre.rs3_release.170928-1534 Machine Name: Kernel base = 0xfffff800`9540d000 PsLoadedModuleList = 0xfffff800`95774110 Debug session time: Wed Feb 28 17:16:23.816 2018 (UTC - 8:00) System Uptime: 0 days 0:00:20.534
Das Debugger-Befehlsfenster ist das wichtigste Debugging-Informationsfenster in WinDbg. In diesem Fenster können Sie Debugger-Befehle eingeben und die Befehlsausgabe ansehen.
Das Debugger-Befehlsfenster ist in zwei Bereiche unterteilt. Geben Sie die Befehle in das kleinere Fenster ein, das das Befehlseingabefenster am unteren Rand des Fensters ist, und sehen Sie die Befehlsausgabe im größeren Fenster am oberen Rand des Fensters.
Verwenden Sie im Befehlseingabebereich die Pfeil-nach-oben- und Pfeil-nach-unten-Tasten, um durch den Befehlsverlauf zu blättern. Wenn ein Befehl erscheint, können Sie ihn bearbeiten oder die Eingabetaste drücken, um den Befehl auszuführen.
Befehle und Techniken zur Fehlersuche im Kernelmodus
In diesem Abschnitt können Sie mit Debug-Befehlen Informationen über das Zielsystem anzeigen.
Einige Debug-Befehle zeigen Text in Debugger Markup Language (DML) an, den Sie auswählen können, um schnell weitere Informationen zu erhalten.
Verwenden Sie auf dem Wirtssystem die Tastenkombination Strg+Rollen-Taste in WinDBg, um in den auf dem Zielsystem laufenden Code einzudringen. Es kann einige Zeit dauern, bis das Zielsystem reagiert.
Geben Sie den folgenden Befehl ein, um DML im Debugger-Befehlsfenster zu aktivieren:
0: kd> .prefer_dml 1 DML versions of commands on by default
Sie können die Hilfe zu den Referenzbefehlen mit dem Befehl
.hh
aufrufen. Geben Sie den folgenden Befehl ein, um die Befehlshilfe für.prefer_dml
anzuzeigen:0: kd> .hh .prefer_dml
Die Hilfedatei des Debuggers zeigt die Hilfe für den Befehl
.prefer_dml
an.Um detaillierte Versionsinformationen auf dem Zielsystem anzuzeigen, geben Sie im WinDbg-Fenster den Befehl vertarget (Show Target Computer Version) ein:
0: kd> vertarget Windows 10 Kernel Version 9926 MP (4 procs) Free x64 Product: WinNt, suite: TerminalServer SingleUserTS Built by: 9926.0.amd64fre.fbl_awesome1501.150119-1648 Machine Name: "" Kernel base = 0xfffff801`8d283000 PsLoadedModuleList = 0xfffff801`8d58aef0 Debug session time: Fri Feb 20 10:15:17.807 2015 (UTC - 8:00) System Uptime: 0 days 01:31:58.931
Um zu überprüfen, ob Sie mit dem richtigen Kernelmodus-Prozess arbeiten, geben Sie im WinDbg-Fenster den Befehl lm (List Loaded Modules) ein, um die geladenen Module anzuzeigen:
0: Kd> lm start end module name fffff801`09200000 fffff801`0925f000 volmgrx (no symbols) fffff801`09261000 fffff801`092de000 mcupdate_GenuineIntel (no symbols) fffff801`092de000 fffff801`092ec000 werkernel (export symbols) werkernel.sys fffff801`092ec000 fffff801`0934d000 CLFS (export symbols) CLFS.SYS fffff801`0934d000 fffff801`0936f000 tm (export symbols) tm.sys fffff801`0936f000 fffff801`09384000 PSHED (export symbols) PSHED.dll fffff801`09384000 fffff801`0938e000 BOOTVID (export symbols) BOOTVID.dll fffff801`0938e000 fffff801`093f7000 spaceport (no symbols) fffff801`09400000 fffff801`094cf000 Wdf01000 (no symbols) fffff801`094d9000 fffff801`09561000 CI (export symbols) CI.dll ...
Ausgelassene Ausgaben sind in diesem Lab mit „...“ gekennzeichnet.
Um detaillierte Informationen über ein bestimmtes Modul anzufordern, verwenden Sie die Option
v
(ausführlich (verbose)):0: Kd> lm v m tcpip Browse full module list start end module name fffff801`09eeb000 fffff801`0a157000 tcpip (no symbols) Loaded symbol image file: tcpip.sys Image path: \SystemRoot\System32\drivers\tcpip.sys Image name: tcpip.sys Browse all global symbols functions data Timestamp: Sun Nov 09 18:59:03 2014 (546029F7) CheckSum: 00263DB1 ImageSize: 0026C000 Translations: 0000.04b0 0000.04e4 0409.04b0 0409.04e4 Unable to enumerate user-mode unloaded modules, Win32 error 0n30
Es gibt keinen festgelegten Symbolpfad und keine geladenen Symbole, so dass im Debugger nur begrenzte Informationen verfügbar sind.
Herunterladen und Erstellen des KMDF-Echo-Treibers
In diesem Abschnitt laden Sie den KMDF-Echotreiber herunter und erstellen ihn.
Normalerweise arbeiten Sie mit Ihrem eigenen Treibercode, wenn Sie WinDbg verwenden. Um sich mit der Funktionsweise von WinDbg vertraut zu machen, wird in dieser Übung der Beispieltreiber KMDF Template „Echo“ verwendet. Zum besseren Verständnis der in WinDbg angezeigten Informationen ist der Quellcode verfügbar. Dieses Beispiel wird auch verwendet, um zu veranschaulichen, wie Sie in einem einzigen Schritt durch nativen Kernelmodus-Code gehen können. Diese Technik kann bei der Fehlersuche in komplexem Kernelmodus-Code hilfreich sein.
Zum Herunterladen und Erstellen des Echo-Beispiel-Audiotreibers:
Laden Sie das KMDF-Echo-Beispiel von GitHub herunter und extrahieren Sie es.
Sehen Sie sich das echo-Beispiel auf GitHub an.
Lesen Sie mehr über das Beispiel.
Durchsuchen Sie alle Windows-Treiberbeispiele.
Das KMDF-Echo-Beispiel befindet sich im Ordner general.
Laden Sie die Treiberbeispiele in einer Zip-Datei herunter: Beispiele für Treiber
Laden Sie die Zip-Datei auf Ihre lokale Festplatte herunter.
Wählen und halten Sie die Zip-Datei oder klicken Sie mit der rechten Maustaste darauf und wählen Sie Extract All. Geben Sie einen neuen Ordner an oder navigieren Sie zu einem vorhandenen Ordner, um die extrahierten Dateien zu speichern. Sie könnten zum Beispiel C:\DriverSamples\ als neuen Ordner angeben, in den die Dateien extrahiert werden sollen.
Nachdem die Dateien extrahiert wurden, wechseln Sie in den folgenden Unterordner: C:\DriverSamples\general\echo\kmdf
Wählen Sie in Microsoft Visual Studio Datei>Öffnen Sie>Project/Solution... und wechseln Sie zu dem Ordner, der die extrahierten Dateien enthält, zum Beispiel C:\DriverSamples\general\echo\kmdf. Doppelklicken Sie auf die Lösungsdatei kmdfecho , um sie zu öffnen.
Suchen Sie in Visual Studio den Solution Explorer. Falls dieses Fenster noch nicht geöffnet ist, wählen Sie Solution Explorer aus dem Menü Ansicht. Im Projektmappen-Explorer sehen Sie eine Projektmappe, die drei Projekte enthält.
Legen Sie die Konfiguration und die Plattform der Probe fest. Wählen Sie im Projektmappen-Explorer mit der rechten Maustaste oder durch Halten Solution 'kmdfecho' (3 projects) und wählen Sie Configuration Manager. Stellen Sie sicher, dass die Konfigurations- und Plattformeinstellungen für alle drei Projekte gleich sind. Standardmäßig ist die Konfiguration auf Win10 Debug und die Plattform auf Win64 für alle Projekte eingestellt. Wenn Sie Konfigurations- oder Plattformänderungen an einem Projekt vornehmen, nehmen Sie die gleichen Änderungen auch an den übrigen drei Projekten vor.
Treibermuster müssen geändert werden, um Werte zu verwenden, die sich nicht mit bestehenden Treibern überschneiden. Unter From Sample Code to Production Driver - What to Change in the Samples erfahren Sie, wie Sie ein einzigartiges Treiberbeispiel erstellen, das mit den in Windows installierten echten Treibern koexistiert.
Legen Sie die Laufzeitbibliothek fest. Öffnen Sie die Eigenschaftsseite des Echo-Treibers und suchen Sie C/C++>Code Generation. Ändern Sie die Laufzeitbibliothek in Multi-Threaded Debug (/MTd). Weitere Informationen zu den Build-Optionen finden Sie unter /MD, /MT, /LD (Use Run-Time Library).
Stellen Sie in den Treibereigenschaften sicher, dass Driver Signing>Sign Mode auf Test Sign eingestellt ist.
Wählen Sie in Visual Studio Build>Build Solution.
Die Build-Fenster sollten eine Meldung anzeigen, dass der Build für alle drei Projekte erfolgreich war.
Tipp
Wenn Sie eine Build-Fehlermeldung erhalten, verwenden Sie die Build-Fehlernummer, um eine Lösung zu finden. Zum Beispiel beschreibt MSBuild-Fehler MSB8040, wie man mit Bibliotheken arbeitet, die durch Spectre abgeschwächt wurden.
Wechseln Sie im Datei-Explorer zu dem Ordner, der die extrahierten Dateien für das Beispiel enthält. Gehen Sie zum Beispiel zu C:\DriverSamples\general\echo\kmdf, wenn dies der Ordner ist, den Sie zuvor angegeben haben. Der Speicherort der kompilierten Treiberdateien innerhalb dieses Ordners hängt von den Konfigurations- und Plattformeinstellungen ab, die Sie im Konfigurationsmanager ausgewählt haben. Wenn Sie die Standardeinstellungen unverändert lassen, werden die kompilierten Treiberdateien in einem Ordner mit dem Namen \x64\Debug für ein 64-Bit-Debug-Build gespeichert.
Wechseln Sie zu dem Ordner, der die erstellten Dateien für den Autosync-Treiber enthält: C:\DriverSamples\general\echo\kmdf\driver\AutoSync\x64\Debug.
Der Ordner sollte diese Dateien enthalten:
Datei Beschreibung Echo.sys Die Treiberdatei. Echo.inf Eine Informationsdatei (INF), die die für die Installation des Treibers erforderlichen Informationen enthält. Außerdem wurde die Datei echoapp.exe erstellt, die sich hier befinden sollte: C:\DriverSamples\general\echo\kmdf\exe\x64\Debug.
Datei Beschreibung EchoApp.exe Eine ausführbare Testdatei der Eingabeaufforderung, die mit dem Treiber echo.sys kommuniziert. Suchen Sie einen USB-Stick oder richten Sie eine Netzwerkfreigabe ein, um die erstellten Treiberdateien und den Test EchoApp vom Host auf das Zielsystem zu kopieren.
Im nächsten Abschnitt kopieren Sie den Code auf das Zielsystem und installieren und testen den Treiber.
Installieren Sie das KMDF-Echo-Treiberbeispiel auf dem Zielsystem
In diesem Abschnitt wird der Echo-Beispieltreiber mit Hilfe des DevCon-Tools installiert.
Der Computer, auf dem Sie den Treiber installieren, wird als Zielcomputer oder als Testcomputer bezeichnet. In der Regel ist dieser Computer von dem Computer getrennt, auf dem Sie das Treiberpaket entwickeln und erstellen. Der Computer, auf dem Sie den Treiber entwickeln und erstellen, wird als Hostcomputer bezeichnet.
Der Prozess des Verschiebens des Treiberpakets auf den Zielcomputer und der Installation des Treibers wird als Deployment bezeichnet.
Bevor Sie einen test-signierten Treiber bereitstellen, bereiten Sie den Zielcomputer vor, indem Sie die Test-Signierung aktivieren. Sie müssen auch das DevCon-Tool in Ihrer WDK-Installation finden und es auf das Zielsystem kopieren.
Führen Sie die folgenden Schritte aus, um den Treiber auf dem Zielsystem zu installieren.
Aktivieren Sie auf dem Zielsystem die signierten Testtreiber:
Öffnen Sie Windows-Einstellungen.
Unter Update und Sicherheit, wählen Sie Wiederherstellung.
Wählen Sie unter Erweitertes Starten, Jetzt neu starten.
Wenn der Computer neu startet, wählen Sie Startoptionen. Wählen Sie in Windows 10 Problembehandlung>Erweiterte Optionen>Starteinstellungen, und wählen Sie dann Neustart.
Wählen Sie Deaktivieren Sie die Durchsetzung der Treibersignatur, indem Sie die Taste F7 drücken.
Starten Sie den Zielcomputer erneut.
Rufen Sie auf dem Hostsystem den Ordner Tools in Ihrer WDK-Installation auf und suchen Sie das Tool DevCon. Schauen Sie zum Beispiel in den folgenden Ordner: C:\Program Files (x86)\Windows Kits\10\Tools\x64\devcon.exe.
Erstellen Sie auf dem Ziel einen Ordner für das erstellte Treiberpaket, zum Beispiel C:\EchoDriver. Kopieren Sie devcon.exe auf das Zielsystem. Suchen Sie das .cer Zertifikat auf dem Hostsystem. Sie befindet sich auf dem Host-Computer im selben Ordner, der auch die erstellten Treiberdateien enthält. Kopieren Sie alle Dateien aus dem zuvor beschriebenen erstellten Treiber auf dem Host-Computer und speichern Sie sie in demselben Ordner, den Sie auf dem Zielcomputer erstellt haben.
Wählen Sie auf dem Zielcomputer die Zertifikatsdatei aus und halten Sie sie gedrückt oder klicken Sie mit der rechten Maustaste darauf und wählen Sie Installieren. Folgen Sie dann den Anweisungen, um das Testzertifikat zu installieren.
Ausführlichere Anweisungen zum Einrichten des Zielcomputers finden Sie unter Vorbereiten eines Computers für die manuelle Treiberbereitstellung.
Die folgenden Anweisungen zeigen Ihnen, wie Sie den Beispieltreiber installieren und testen können. Hier ist die allgemeine Syntax für das devcon-Tool, das Sie zur Installation des Treibers verwenden:
devcon install <INF file> <hardware ID>
Die für die Installation dieses Treibers erforderliche INF-Datei lautet echo.inf. Die Inf-Datei enthält die Hardware-ID für die Installation der echo.sys. Für das Echo-Beispiel lautet die Hardware-ID root\ECHO.
Öffnen Sie auf dem Zielcomputer ein Eingabeaufforderungsfenster als Administrator. Gehen Sie zu Ihrem Treiberpaketordner und geben Sie den folgenden Befehl ein:
devcon install echo.inf root\ECHO
Wenn Sie eine Fehlermeldung erhalten, dass devcon nicht erkannt wird, versuchen Sie, den Pfad zum Tool devcon hinzuzufügen. Wenn Sie sie beispielsweise in einen Ordner mit dem Namen C:\Tools kopiert haben, versuchen Sie es mit dem folgenden Befehl:
c:\tools\devcon install echo.inf root\ECHO
Es erscheint ein Dialogfeld, das anzeigt, dass der Testtreiber ein unsignierter Treiber ist. Wählen Sie Diesen Treiber trotzdem installieren, um fortzufahren.
Tipp
Wenn Sie Probleme mit der Installation haben, finden Sie in der folgenden Datei weitere Informationen. %windir%\inf\setupapi.dev.log
Nachdem Sie den Beispieltreiber erfolgreich installiert haben, können Sie ihn nun testen.
Geben Sie auf dem Zielcomputer in einem Eingabeaufforderungsfenster devmgmt ein, um den Geräte-Manager zu öffnen. Wählen Sie im Geräte-Manager im Menü Ansicht die Option Geräte nach Typ. Suchen Sie in der Gerätestruktur Sample WDF Echo Driver im Knoten Sample Device.
Geben Sie echoapp ein, um die Test-Echo-App zu starten und zu überprüfen, ob der Treiber funktioniert.
C:\Samples\KMDF_Echo_Sample> echoapp
DevicePath: \\?\root#sample#0005#{cdc35b6e-0be4-4936-bf5f-5537380a7c1a}
Opened device successfully
512 Pattern Bytes Written successfully
512 Pattern Bytes Read successfully
Pattern Verified successfully
30720 Pattern Bytes Written successfully
30720 Pattern Bytes Read successfully
Pattern Verified successfully
Verwenden von WinDbg, um Informationen über den Treiber anzuzeigen
In diesem Abschnitt legen Sie den Symbolpfad fest und verwenden Kernel-Debugger-Befehle, um Informationen über den KMDF-Echo-Beispieltreiber anzuzeigen.
Zum Anzeigen von Informationen über den Treiber:
Wenn Sie den Debugger auf dem Hostsystem geschlossen haben, öffnen Sie ihn erneut, indem Sie den folgenden Befehl im Administrator-Eingabeaufforderungsfenster eingeben.
WinDbg -k net:port=50000,key=2steg4fzbj2sz.23418vzkd4ko3.1g34ou07z4pev.1sp3yo9yz874p
Verwenden Sie die Tastenkombination Strg+Break (Rollen-Taste), um in den Code des Zielsystems einzudringen.
Um den Symbolpfad zum Microsoft-Symbolserver in der WinDbg-Umgebung festzulegen, verwenden Sie den Befehl
.symfix
.0: kd> .symfix
Um Ihren lokalen Symbolort hinzuzufügen, um Ihre lokalen Symbole zu verwenden, fügen Sie den Pfad mit
.sympath+
und dann.reload /f
hinzu.0: kd> .sympath+ C:\DriverSamples\general\echo\kmdf 0: kd> .reload /f
Der Befehl
.reload
mit der Option/f
force löscht alle Symbolinformationen für das angegebene Modul und lädt die Symbole neu. In einigen Fällen wird mit diesem Befehl auch das Modul selbst neu geladen oder entladen.
Sie müssen die richtigen Symbole laden, um die erweiterten Funktionen von WinDbg nutzen zu können. Wenn Sie die Symbole nicht richtig konfiguriert haben, erhalten Sie beim Versuch, Funktionen zu verwenden, die von Symbolen abhängig sind, Meldungen, dass die Symbole nicht verfügbar sind.
0:000> dv
Unable to enumerate locals, HRESULT 0x80004005
Private symbols (symbols.pri) are required for locals.
Type “.hh dbgerr005” for details.
Für die Arbeit mit Symbolen gibt es viele Ansätze. In vielen Situationen können Sie den Computer so konfigurieren, dass er bei Bedarf auf Symbole von einem Symbolserver zugreift, den Microsoft bereitstellt. Dieses Lab verwendet diesen Ansatz. Wenn sich die Symbole in Ihrer Umgebung an einem anderen Ort befinden, ändern Sie die Schritte, um diesen Ort zu verwenden. Weitere Informationen finden Sie unter Symbolpfad für Windows-Debugger.
Um Quellcode-Debugging durchzuführen, müssen Sie eine geprüfte (Debug-)Version Ihrer Binärdateien erstellen. Der Compiler erstellt Symboldateien (.pdb Dateien). Diese Symboldateien zeigen dem Debugger, wie die Binäranweisungen den Quellzeilen entsprechen. Die eigentlichen Quelldateien selbst müssen auch für den Debugger zugänglich sein.
Die Symboldateien enthalten nicht den Text des Quellcodes. Für das Debugging ist es am besten, wenn der Linker Ihren Code nicht optimiert. Das Debuggen des Quellcodes und der Zugriff auf lokale Variablen sind schwieriger und manchmal fast unmöglich, wenn der Code optimiert wurde. Wenn Sie Probleme mit der Anzeige von lokalen Variablen oder Quellcodezeilen haben, setzen Sie die folgenden Build-Optionen:
set COMPILE_DEBUG=1
set ENABLE_OPTIMIZER=0
Geben Sie den folgenden Befehl in den Befehlsbereich des Debuggers ein, um Informationen über den Echotreiber anzuzeigen:
0: kd> lm m echo* v Browse full module list start end module name fffff801`4ae80000 fffff801`4ae89000 ECHO (private pdb symbols) C:\Samples\KMDF_ECHO_SAMPLE\echo.pdb Loaded symbol image file: ECHO.sys Image path: \SystemRoot\system32\DRIVERS\ECHO.sys Image name: ECHO.sys ...
Weitere Informationen finden Sie unter lm.
Da dieses Labset
prefer_dml
früher erstellt wurde, sind einige Elemente der Ausgabe Hot Links, die Sie auswählen können. Wählen Sie den Link Browse all global symbols in der Debug-Ausgabe, um Informationen über Elemente anzuzeigen, die mit dem Buchstaben „a“ beginnen.0: kd> x /D Echo!a*
Das Echo-Beispiel enthält keine Symbole, die mit dem Buchstaben „a“ beginnen. Geben Sie daher
x ECHO!Echo*
ein, um Informationen über alle mit dem Echo-Treiber verbundenen Symbole anzuzeigen, die mit „Echo“ beginnen.0: kd> x ECHO!Echo* fffff801`0bf95690 ECHO!EchoEvtIoQueueContextDestroy (void *) fffff801`0bf95000 ECHO!EchoEvtDeviceSelfManagedIoStart (struct WDFDEVICE__ *) fffff801`0bf95ac0 ECHO!EchoEvtTimerFunc (struct WDFTIMER__ *) fffff801`0bf9b120 ECHO!EchoEvtDeviceSelfManagedIoSuspend (struct WDFDEVICE__ *) ...
Weitere Informationen finden Sie unter x (Symbole untersuchen).
Die Erweiterung
!lmi
zeigt detaillierte Informationen über ein Modul an. Geben Sie!lmi echo
ein. Ihre Ausgabe sollte dem in diesem Beispiel gezeigten Text ähnlich sein:0: kd> !lmi echo Loaded Module Info: [echo] Module: ECHO Base Address: fffff8010bf94000 Image Name: ECHO.sys …
Verwenden Sie die Erweiterung
!dh
, um Kopfinformationen anzuzeigen, wie in diesem Beispiel gezeigt:0: kd> !dh echo File Type: EXECUTABLE IMAGE FILE HEADER VALUES 14C machine (i386) 6 number of sections 54AD8A42 time date stamp Wed Jan 07 11:34:26 2015 ...
Geben Sie Folgendes ein, um die Standard-Debug-Bitmaske so zu ändern, dass alle Debug-Meldungen des Zielsystems im Debugger angezeigt werden:
0: kd> ed nt!Kd_DEFAULT_MASK 0xFFFFFFFF
Einige Treiber zeigen zusätzliche Informationen an, wenn die Maske von 0xFFFFFFFF verwendet wird. Setzen Sie die Maske auf 0x00000000, wenn Sie die Menge der angezeigten Informationen reduzieren möchten.
0: kd> ed nt!Kd_DEFAULT_MASK 0x00000000
Verwenden Sie den Befehl
dd
, um sicherzustellen, dass die Maske so eingestellt ist, dass alle Debugger-Meldungen angezeigt werden.0: kd> dd nt!kd_DEFAULT_MASK fffff802`bb4057c0 ffffffff 00000000 00000000 00000000 fffff802`bb4057d0 00000000 00000000 00000000 00000000 fffff802`bb4057e0 00000001 00000000 00000000 00000000 fffff802`bb4057f0 00000000 00000000 00000000 00000000 fffff802`bb405800 00000000 00000000 00000000 00000000 fffff802`bb405810 00000000 00000000 00000000 00000000 fffff802`bb405820 00000000 00000000 00000000 00000000 fffff802`bb405830 00000000 00000000 00000000 00000000
Anzeigen von Plug-and-Play-Gerätestrukturinformationen
Zeigen Sie in diesem Abschnitt Informationen über den Echo-Beispielgerätetreiber an und wo er sich in der Plug-and-Play-Gerätestruktur befindet.
Informationen über den Gerätetreiber in der Plug-and-Play-Gerätestruktur können bei der Fehlersuche hilfreich sein. Wenn beispielsweise ein Gerätetreiber nicht in der Gerätestruktur vorhanden ist, liegt möglicherweise ein Problem mit der Installation des Gerätetreibers vor.
Weitere Informationen über die Debug-Erweiterung für Geräteknoten finden Sie unter !devnode.
Geben Sie auf dem Hostsystem den Befehl
!devnode 0 1
ein, um alle Geräteknoten in der Plug-and-Play-Gerätestruktur anzuzeigen.0: kd> !devnode 0 1 Dumping IopRootDeviceNode (= 0xffffe0005a3a8d30) DevNode 0xffffe0005a3a8d30 for PDO 0xffffe0005a3a9e50 InstancePath is "HTREE\ROOT\0" State = DeviceNodeStarted (0x308) Previous State = DeviceNodeEnumerateCompletion (0x30d) DevNode 0xffffe0005a3a3d30 for PDO 0xffffe0005a3a4e50 InstancePath is "ROOT\volmgr\0000" ServiceName is "volmgr" State = DeviceNodeStarted (0x308) Previous State = DeviceNodeEnumerateCompletion (0x30d) DevNode 0xffffe0005a324560 for PDO 0xffffe0005bd95ca0… …
Verwenden Sie Strg+F, um in der erzeugten Ausgabe nach dem Namen des Gerätetreibers zu suchen, echo.
Der Echo-Gerätetreiber sollte geladen sein. Verwenden Sie den Befehl
!devnode 0 1 echo
, um Plug-and-Play-Informationen zu Ihrem Echo-Gerätetreiber anzuzeigen, wie in diesem Beispiel gezeigt:0: Kd> !devnode 0 1 echo Dumping IopRootDeviceNode (= 0xffffe0007b725d30) DevNode 0xffffe0007b71a630 for PDO 0xffffe0007b71a960 InstancePath is "ROOT\SAMPLE\0000" ServiceName is "ECHO" State = DeviceNodeStarted (0x308) Previous State = DeviceNodeEnumerateCompletion (0x30d) …
Die im vorherigen Befehl angezeigte Ausgabe enthält das PDO, das mit der laufenden Instanz Ihres Treibers verbunden ist, in diesem Beispiel 0xffffe0007b71a960. Geben Sie den Befehl
!devobj <PDO address>
ein, um die mit dem Echo-Gerätetreiber verbundenen Plug-and-Play-Informationen anzuzeigen. Verwenden Sie die PDO-Adresse, die!devnode
auf Ihrem Computer anzeigt, nicht die hier angegebene.0: kd> !devobj 0xffffe0007b71a960 Device object (ffffe0007b71a960) is for: 0000000e \Driver\PnpManager DriverObject ffffe0007b727e60 Current Irp 00000000 RefCount 0 Type 00000004 Flags 00001040 Dacl ffffc102c9b36031 DevExt 00000000 DevObjExt ffffe0007b71aab0 DevNode ffffe0007b71a630 ExtensionFlags (0x00000800) DOE_DEFAULT_SD_PRESENT Characteristics (0x00000180) FILE_AUTOGENERATED_DEVICE_NAME, FILE_DEVICE_SECURE_OPEN AttachedDevice (Upper) ffffe000801fee20 \Driver\ECHO Device queue is not busy.
Die mit dem Befehl
!devnode 0 1
angezeigte Ausgabe enthält die PDO-Adresse, die mit der laufenden Instanz Ihres Treibers verknüpft ist, in diesem Beispiel ist es 0xffffe0007b71a960. Geben Sie den Befehl!devstack <PDO address>
ein, um die mit dem Gerätetreiber verbundenen Plug-and-Play-Informationen anzuzeigen. Verwenden Sie die PDO-Adresse, die!devnode
auf Ihrem Computer anzeigt, nicht die in diesem Beispiel gezeigte Adresse.0: kd> !devstack 0xffffe0007b71a960 !DevObj !DrvObj !DevExt ObjectName ffffe000801fee20 \Driver\ECHO ffffe0007f72eff0 > ffffe0007b71a960 \Driver\PnpManager 00000000 0000000e !DevNode ffffe0007b71a630 : DeviceInst is "ROOT\SAMPLE\0000" ServiceName is "ECHO"
Die Ausgabe zeigt, dass Sie einen recht einfachen Gerätetreiberstapel haben. Der Echo-Treiber ist ein untergeordneter Knoten des PnPManager. PnPManager ist ein Wurzelknoten.
\Driver\ECHO
\Driver\PnpManager
Dieses Diagramm zeigt einen komplexeren Geräteknotenbaum.
Weitere Informationen über komplexere Treiberstapel finden Sie unter Treiberstapel und Geräteknoten und Gerätestapel.
Arbeiten mit Haltepunkten und Quellcode
In diesem Abschnitt setzen Sie Haltepunkte und gehen in Einzelschritten durch den Kernelmodus-Quellcode.
Um den Code schrittweise zu durchlaufen und die Werte von Variablen in Echtzeit zu überprüfen, aktivieren Sie Haltepunkte und legen Sie einen Pfad zum Quellcode fest.
Haltepunkte stoppen die Codeausführung an einer bestimmten Codezeile. Gehen Sie ab diesem Punkt im Code vorwärts, um diesen speziellen Codeabschnitt zu debuggen.
Um einen Haltepunkt mit einem Debug-Befehl zu setzen, verwenden Sie einen der folgenden b
Befehle.
Befehl | Beschreibung |
---|---|
bp |
Setzt einen Haltepunkt, der aktiv ist, bis das Modul, in dem er sich befindet, entladen wird. |
bu |
Setzt einen Haltepunkt, der nicht aufgelöst wird, wenn das Modul entladen wird, und der wieder aktiviert wird, wenn das Modul neu geladen wird. |
bm |
Setzt einen Haltepunkt für ein Symbol. Dieser Befehl verwendet bu oder bp entsprechend und erlaubt die Verwendung von Platzhaltern (* ), um Haltepunkte für jedes übereinstimmende Symbol zu setzen, wie z.B. alle Methoden in einer Klasse. |
Weitere Informationen finden Sie unter Quellcode-Debugging in WinDbg.
Verwenden Sie auf dem Hostsystem die WinDbg-Benutzeroberfläche, um zu bestätigen, dass Debug>Source Mode in der aktuellen WinDbg-Sitzung aktiviert ist.
Geben Sie den folgenden Befehl ein, um Ihren lokalen Codespeicherort zum Quellpfad hinzuzufügen:
.srcpath+ C:\DriverSamples\KMDF_Echo_Sample\driver\AutoSync
Geben Sie den folgenden Befehl ein, um Ihr lokales Symbol in den Symbolpfad aufzunehmen:
.sympath+ C:\DriverSamples\KMDF_Echo_Sample\driver\AutoSync
Verwenden Sie den Befehl
x
, um die mit dem Echo-Treiber verbundenen Symbole zu untersuchen und den Funktionsnamen für den Haltepunkt zu bestimmen. Sie können einen Platzhalter oder die Tastenkombination Strg+F verwenden, um den FunktionsnamenDeviceAdd
zu finden.0: kd> x ECHO!EchoEvt* 8b4c7490 ECHO!EchoEvtIoQueueContextDestroy (void *) 8b4c7000 ECHO!EchoEvtDeviceSelfManagedIoStart (struct WDFDEVICE__ *) 8b4c7820 ECHO!EchoEvtTimerFunc (struct WDFTIMER__ *) 8b4cb0e0 ECHO!EchoEvtDeviceSelfManagedIoSuspend (struct WDFDEVICE__ *) 8b4c75d0 ECHO!EchoEvtIoWrite (struct WDFQUEUE__ *, struct WDFREQUEST__ *, unsigned int) 8b4cb170 ECHO!EchoEvtDeviceAdd (struct WDFDRIVER__ *, struct …
Die Ausgabe zeigt, dass
DeviceAdd
Methode für Ihren Echo-TreiberECHO!EchoEvtDeviceAdd
ist.Alternativ können Sie auch den Quellcode überprüfen, um den Funktionsnamen für Ihren Haltepunkt zu finden.
Setzen Sie den Haltepunkt mit dem Befehl
bm
. Geben Sie dabei den Namen des Treibers ein, gefolgt von dem Funktionsnamen, z. B.AddDevice
, an dem Sie den Haltepunkt setzen wollen, getrennt durch ein Ausrufezeichen. In diesem Lab wirdAddDevice
verwendet, um das Laden des Treibers zu beobachten.0: kd> bm ECHO!EchoEvtDeviceAdd 1: fffff801`0bf9b1c0 @!"ECHO!EchoEvtDeviceAdd"
Sie können eine andere Syntax in Verbindung mit dem Setzen von Variablen wie
<module>!<symbol>
,<class>::<method>
,'<file.cpp>:<line number>'
oder mehrmals überspringen<condition> <#>
verwenden. Weitere Informationen finden Sie unter Bedingte Haltepunkte in WinDbg und anderen Windows-Debuggern.Listen Sie die aktuellen Haltepunkte auf, um zu bestätigen, dass der Haltepunkt durch Eingabe des Befehls
bl
gesetzt wurde:0: kd> bl 1 e fffff801`0bf9b1c0 0001 (0001) ECHO!EchoEvtDeviceAdd
Das „e“ in der hier gezeigten Ausgabe zeigt an, dass der Haltepunkt Nummer 1 aktiviert ist und ausgelöst wird.
Starten Sie die Codeausführung auf dem Zielsystem neu, indem Sie den Befehl
g
(go) eingeben.Öffnen Sie auf dem Zielsystem unter Windows Device Manager über das Symbol oder durch Eingabe von mmc devmgmt.msc. Erweitern Sie im Geräte-Manager den Knoten Samples.
Halten Sie den Eintrag für den KMDF-Echotreiber gedrückt oder klicken Sie mit der rechten Maustaste darauf und wählen Sie Deaktivieren aus dem Menü.
Halten Sie die Maustaste gedrückt oder klicken Sie erneut mit der rechten Maustaste auf den KMDF-Echotreibereintrag und wählen Sie Enable aus dem Menü.
Wenn der Treiber auf dem Hostsystem aktiviert ist, sollte der Debug-Haltepunkt AddDevice ausgelöst werden. Die Ausführung des Treibercodes auf dem Zielsystem sollte angehalten werden. Wenn der Haltepunkt erreicht ist, sollte die Ausführung am Anfang der Routine AddDevice angehalten werden. Die Ausgabe des Debug-Befehls zeigt
Breakpoint 1 hit
an.Gehen Sie den Code Zeile für Zeile durch, indem Sie den Befehl
p
eingeben oder F10 drücken, bis Sie das folgende Ende der Routine AddDevice erreichen. Das Klammerzeichen (}
) ist wie abgebildet hervorgehoben.
Im nächsten Abschnitt wird der Zustand der Variablen nach Ausführung des DeviceAdd-Codes untersucht.
Sie können vorhandene Haltepunkte mit den folgenden Befehlen ändern:
Befehl | Beschreibung |
---|---|
bl |
Listet Haltepunkte auf. |
bc |
Löscht einen Haltepunkt aus der Liste. Verwenden Sie bc * , um alle Haltepunkte zu löschen. |
bd |
Deaktiviert einen Haltepunkt. Verwenden Sie bd * , um alle Haltepunkte zu deaktivieren. |
be |
Aktiviert einen Haltepunkt. Verwenden Sie be * , um alle Haltepunkte zu aktivieren. |
Alternativ dazu können Sie Haltepunkte auch in der WinDbg-Benutzeroberfläche ändern.
Sie können auch Haltepunkte setzen, die ausgelöst werden, wenn auf eine Speicherstelle zugegriffen wird. Verwenden Sie den Befehl ba
(break on access) mit der folgenden Syntax:
ba <access> <size> <address> {options}
Option | Beschreibung |
---|---|
e |
Ausführen: wenn die CPU einen Befehl von der Adresse abruft |
r |
Lesen/Schreiben: wenn die CPU die Adresse liest oder schreibt |
w |
Schreiben: wenn die CPU an die Adresse schreibt |
Sie können immer nur vier Daten-Haltepunkte gleichzeitig setzen. Es liegt an Ihnen, sicherzustellen, dass Sie Ihre Daten richtig ausrichten, um den Haltepunkt auszulösen. Wörter müssen auf Adressen enden, die durch 2 teilbar sind, Wörter müssen durch 4 teilbar sein, und Vierfachwörter durch 0 oder 8.
Um zum Beispiel einen Lese-/Schreib-Haltepunkt an einer bestimmten Speicheradresse zu setzen, könnten Sie einen Befehl wie den folgenden verwenden.
ba r 4 0x0003f7bf0
Sie können die folgenden Befehle verwenden, um durch Ihren Code zu gehen, wobei die zugehörigen Tastaturkürzel in Klammern angegeben sind.
- Break in (Strg+Break). Dieser Befehl unterbricht ein System, solange es läuft und mit WinDbg in Verbindung steht. Die Reihenfolge im Kernel-Debugger ist Strg+C.
- Zum Cursor laufen (F7 oder Strg+F10). Platzieren Sie den Cursor in einem Quellcode- oder Disassemblierungsfenster an der Stelle, an der die Ausführung unterbrochen werden soll, und drücken Sie dann F7. Der Code wird bis zu diesem Punkt ausgeführt. Wenn der Ablauf der Codeausführung nicht den vom Cursor angezeigten Punkt erreicht, bricht WinDbg nicht ab. Diese Situation kann eintreten, wenn eine IF-Anweisung nicht ausgeführt wird.
- Ausführen (F5). Ausführen, bis ein Haltepunkt erreicht wird oder ein Ereignis wie eine Fehlerprüfung eintritt.
- Übertreten (F10). Dieser Befehl veranlasst die Ausführung des Codes um jeweils eine Anweisung oder einen Befehl. Trifft man auf einen Aufruf, wird der Code über den Aufruf hinweg ausgeführt, ohne in die aufgerufene Routine einzutreten. Wenn die Programmiersprache C oder C++ ist und WinDbg sich im Quellcode-Modus befindet, kann der Quellcode-Modus mit Debug>Source Mode ein- oder ausgeschaltet werden.
- Treten Sie ein (F11). Dieser Befehl entspricht dem Step-Over-Befehl, mit dem Unterschied, dass die Ausführung eines Aufrufs in die aufgerufene Routine geht.
- Aussteigen (Umschalt+F11). Dieser Befehl bewirkt, dass die Ausführung bis zur aktuellen Routine oder der aktuellen Stelle im Aufrufstapel läuft und dort beendet wird. Dieser Befehl ist nützlich, wenn Sie genug von der Routine gesehen haben.
Weitere Informationen finden Sie unter Quellcode-Debugging in WinDbg.
Variablen und Aufrufstapel anzeigen
In diesem Abschnitt werden Informationen über Variablen und Aufrufstapel angezeigt.
In dieser Übung wird davon ausgegangen, dass Sie bei der Routine AddDevice mit dem zuvor beschriebenen Verfahren angehalten haben. Um die hier gezeigte Ausgabe zu sehen, wiederholen Sie die zuvor beschriebenen Schritte, falls erforderlich.
Auf dem Hostsystem können Sie mit dem Menüpunkt view>local lokale Variablen anzeigen.
Um den Speicherort einer globalen Variablenadresse zu finden, geben Sie ? <variable name>
ein.
- Step out (Shift+F11) – Dieser Befehl veranlasst die Ausführung bis zur aktuellen Routine (aktuelle Position im Aufrufstapel) und verlässt diese. Dies ist nützlich, wenn Sie genug von der Routine gesehen haben.
Weitere Informationen finden Sie unter Source Code Debugging in WinDbg (Classic) in der Debugging-Referenzdokumentation.
Abschnitt 8: Anzeigen von Variablen und Aufrufstapeln
In Abschnitt 8 werden Sie Informationen über Variablen und Aufrufstapel anzeigen.
In dieser Übung wird davon ausgegangen, dass Sie bei der Routine AddDevice mit dem zuvor beschriebenen Verfahren angehalten haben. Um die hier gezeigte Ausgabe zu sehen, wiederholen Sie die zuvor beschriebenen Schritte, falls erforderlich.
<– Auf dem Hostsystem
Variablen anzeigen
Verwenden Sie den Menüpunkt view>local, um lokale Variablen anzuzeigen.
Globale Variablen
Sie können den Ort einer globalen Variablenadresse finden, indem Sie ? <Name der Variablen>.
Lokale Variablen
Sie können die Namen und Werte aller lokalen Variablen für einen bestimmten Frame anzeigen, indem Sie den Befehl dv eingeben.
Um die Namen und Werte aller lokalen Variablen für einen bestimmten Frame anzuzeigen, geben Sie den Befehl dv
ein:
0: kd> dv
Driver = 0x00001fff`7ff9c838
DeviceInit = 0xffffd001`51978190
status = 0n0
Der Aufrufstapel ist die Kette von Funktionsaufrufen, die zur aktuellen Position des Programmzählers geführt haben. Die oberste Funktion auf dem Aufrufstapel ist die aktuelle Funktion, die nächste Funktion ist die Funktion, die die aktuelle Funktion aufgerufen hat, und so weiter.
Um den Aufrufstapel anzuzeigen, verwenden Sie die Befehle k*
.
Befehl | Beschreibung |
---|---|
kb |
Zeigt den Stack und die ersten drei Parameter an. |
kp |
Zeigt die Stapel und die vollständige Liste der Parameter an. |
kn |
Ermöglicht die Anzeige des Stapels mit den daneben liegenden Frameinformationen. |
Wenn Sie den Aufrufstapel auf dem Hostsystem verfügbar halten möchten, wählen Sie view>call stack, um ihn anzuzeigen. Wählen Sie die Spalten am oberen Rand des Fensters aus, um die Anzeige zusätzlicher Informationen umzuschalten.
Verwenden Sie das Kommando
kn
, um den Aufrufstapel beim Debuggen des Beispieladaptercodes in einem Break-Status anzuzeigen.3: kd> kn # Child-SP RetAddr Call Site 00 ffffd001`51978110 fffff801`0942f55b ECHO!EchoEvtDeviceAdd+0x66 [c:\Samples\kmdf echo sample\c++\driver\autosync\driver.c @ 138] 01 (Inline Function) --------`-------- Wdf01000!FxDriverDeviceAdd::Invoke+0x30 [d:\wbrtm\minkernel\wdf\framework\shared\inc\private\common\fxdrivercallbacks.hpp @ 61] 02 ffffd001`51978150 fffff801`eed8097d Wdf01000!FxDriver::AddDevice+0xab [d:\wbrtm\minkernel\wdf\framework\shared\core\km\fxdriverkm.cpp @ 72] 03 ffffd001`51978570 fffff801`ef129423 nt!PpvUtilCallAddDevice+0x35 [d:\9142\minkernel\ntos\io\pnpmgr\verifier.c @ 104] 04 ffffd001`519785b0 fffff801`ef0c4112 nt!PnpCallAddDevice+0x63 [d:\9142\minkernel\ntos\io\pnpmgr\enum.c @ 7397] 05 ffffd001`51978630 fffff801`ef0c344f nt!PipCallDriverAddDevice+0x6e2 [d:\9142\minkernel\ntos\io\pnpmgr\enum.c @ 3390] ...
Der Aufrufstapel zeigt, dass der Kernel (nt) den Plug-and-Play-Code (PnP) aufruft, der den Treiberrahmencode (WDF) aufruft, der wiederum die Funktion des Echo-Treibers DeviceAdd
aufruft.
Anzeigen von Prozessen und Threads
In diesem Abschnitt werden Informationen über die im Kernelmodus laufenden Prozesse und Threads angezeigt.
Prozesse
Sie können Prozessinformationen mit der Debugger-Erweiterung !process anzeigen oder einstellen. Setzen Sie einen Haltepunkt, um den Prozess zu untersuchen, der verwendet wird, wenn ein Ton abgespielt wird.
Geben Sie auf dem Hostsystem den Befehl
dv
ein, um die mit der RoutineEchoEvtIo
verbundenen Gebietsschema-Variablen zu prüfen:0: kd> dv ECHO!EchoEvtIo* ECHO!EchoEvtIoQueueContextDestroy ECHO!EchoEvtIoWrite ECHO!EchoEvtIoRead
Löschen Sie die vorherigen Haltepunkte mit
bc *
:0: kd> bc *
Setzen Sie mit dem folgenden Befehl einen Symbol-Haltepunkt für die Routinen
EchoEvtIo
:0: kd> bm ECHO!EchoEvtIo* 2: aade5490 @!”ECHO!EchoEvtIoQueueContextDestroy” 3: aade55d0 @!”ECHO!EchoEvtIoWrite” 4: aade54c0 @!”ECHO!EchoEvtIoRead”
Listen Sie die Haltepunkte auf, um zu bestätigen, dass der Haltepunkt richtig gesetzt ist:
0: kd> bl 1 e aabf0490 [c:\Samples\kmdf echo sample\c++\driver\autosync\queue.c @ 197] 0001 (0001) ECHO!EchoEvtIoQueueContextDestroy ...
Geben Sie
g
ein, um die Codeausführung erneut zu starten:0: kd> g
Führen Sie auf dem Zielsystem das
EchoApp.exe
Treiber-Testprogramm auf dem Zielsystem aus.Wenn die Testanwendung auf dem Hostsystem läuft, wird die E/A-Routine im Treiber aufgerufen. Durch diesen Aufruf wird der Haltepunkt ausgelöst, und die Ausführung des Treibercodes auf dem Zielsystem wird angehalten.
Breakpoint 2 hit ECHO!EchoEvtIoWrite: fffff801`0bf95810 4c89442418 mov qword ptr [rsp+18h],r8
Verwenden Sie den Befehl
!process
, um den aktuellen Prozess anzuzeigen, der an der Ausführung von echoapp.exe beteiligt ist:0: kd> !process PROCESS ffffe0007e6a7780 SessionId: 1 Cid: 03c4 Peb: 7ff7cfec4000 ParentCid: 0f34 DirBase: 1efd1b000 ObjectTable: ffffc001d77978c0 HandleCount: 34. Image: echoapp.exe VadRoot ffffe000802c79f0 Vads 30 Clone 0 Private 135. Modified 5. Locked 0. DeviceMap ffffc001d83c6e80 Token ffffc001cf270050 ElapsedTime 00:00:00.052 UserTime 00:00:00.000 KernelTime 00:00:00.000 QuotaPoolUsage[PagedPool] 33824 QuotaPoolUsage[NonPagedPool] 4464 Working Set Sizes (now,min,max) (682, 50, 345) (2728KB, 200KB, 1380KB) PeakWorkingSetSize 652 VirtualSize 16 Mb PeakVirtualSize 16 Mb PageFaultCount 688 MemoryPriority BACKGROUND BasePriority 8 CommitCharge 138 THREAD ffffe00080e32080 Cid 03c4.0ec0 Teb: 00007ff7cfece000 Win32Thread: 0000000000000000 RUNNING on processor 1
Die Ausgabe zeigt, dass der Prozess mit dem Thread echoapp.exe verbunden ist, der ausgeführt wurde, als Ihr Haltepunkt für das Treiber-Schreibereignis erreicht wurde. Für weitere Informationen siehe !process.
Verwenden Sie
!process 0 0
, um zusammenfassende Informationen für alle Prozesse anzuzeigen. Verwenden Sie in der Ausgabe die Tastenkombination Strg+F, um die gleiche Prozessadresse für den Prozess zu finden, der mit dem echoapp.exe Image verbunden ist. In diesem Beispiel lautet die Prozessadresseffffe0007e6a7780
.... PROCESS ffffe0007e6a7780 SessionId: 1 Cid: 0f68 Peb: 7ff7cfe7a000 ParentCid: 0f34 DirBase: 1f7fb9000 ObjectTable: ffffc001cec82780 HandleCount: 34. Image: echoapp.exe ...
Notieren Sie die Prozess-ID, die mit echoapp.exe verknüpft ist, um sie später in diesem Lab zu verwenden. Sie können auch Strg+C verwenden, um die Adresse zur späteren Verwendung in den Kopierpuffer zu kopieren.
_____________________________________________________(echoapp.exe – Prozessadresse)
Geben Sie
g
wie erforderlich in den Debugger ein, um den Code vorwärts laufen zu lassen, bis echoapp.exe beendet ist. Es trifft den Haltepunkt im Lese- und Schreibereignis viele Male. Wenn echoapp.exe beendet ist, wechseln Sie in den Debugger, indem Sie Strg+ScrLk (Strg+Break) drücken.Verwenden Sie den Befehl
!process
, um zu bestätigen, dass Sie einen anderen Prozess ausführen. In der hier gezeigten Ausgabe unterscheidet sich der Prozess mit dem Image-Wert von System vom Image-Wert von Echo.1: kd> !process PROCESS ffffe0007b65d900 SessionId: none Cid: 0004 Peb: 00000000 ParentCid: 0000 DirBase: 001ab000 ObjectTable: ffffc001c9a03000 HandleCount: 786. Image: System VadRoot ffffe0007ce45930 Vads 14 Clone 0 Private 22. Modified 131605. Locked 64. DeviceMap ffffc001c9a0c220 Token ffffc001c9a05530 ElapsedTime 21:31:02.516 ...
Die Ausgabe zeigt, dass ein Systemprozess ffffe0007b65d900 ausgeführt wurde, als Sie das Betriebssystem gestoppt haben.
Verwenden Sie den Befehl
!process
, um die Prozess-ID zu ermitteln, die mit der zuvor aufgezeichneten echoapp.exe verbunden war. Geben Sie Ihre echoapp.exe Prozessadresse an, die Sie zuvor aufgezeichnet haben, und nicht die in diesem Beispiel gezeigte Prozessadresse.0: kd> !process ffffe0007e6a7780 TYPE mismatch for process object at 82a9acc0
Das Prozessobjekt ist nicht mehr verfügbar, da der Prozess echoapp.exe nicht mehr läuft.
Threads
Die Befehle zum Anzeigen und Einstellen von Threads ähneln den Befehlen für Prozesse. Verwenden Sie den Befehl !thread, um Threads anzuzeigen. Verwenden Sie .thread, um die aktuellen Threads festzulegen.
Geben Sie auf dem Hostsystem
g
in den Debugger ein, um die Codeausführung auf dem Zielsystem neu zu starten.Führen Sie auf dem Zielsystem das Treiber-Testprogramm EchoApp.exe aus.
Auf dem Hostsystem wird der Haltepunkt erreicht und die Codeausführung angehalten.
Breakpoint 4 hit ECHO!EchoEvtIoRead: aade54c0 55 push ebp
Um die laufenden Threads anzuzeigen, geben Sie !thread ein. Es sollten Informationen ähnlich dem folgenden Beispiel angezeigt werden:
0: kd> !thread THREAD ffffe000809a0880 Cid 0b28.1158 Teb: 00007ff7d00dd000 Win32Thread: 0000000000000000 RUNNING on processor 0 IRP List: ffffe0007bc5be10: (0006,01f0) Flags: 00060a30 Mdl: 00000000 Not impersonating DeviceMap ffffc001d83c6e80 Owning Process ffffe0008096c900 Image: echoapp.exe ...
Notieren Sie sich den Image-Namen von echoapp.exe. Das bedeutet, dass Sie den mit der Testanwendung verbundenen Thread betrachten.
Verwenden Sie den Befehl
!process
, um festzustellen, ob dieser Thread der einzige Thread ist, der in dem mit echoapp.exe verbundenen Prozess läuft. Die Thread-Nummer des laufenden Threads im Prozess ist derselbe laufende Thread, den der Befehl!thread
anzeigt.0: kd> !process PROCESS ffffe0008096c900 SessionId: 1 Cid: 0b28 Peb: 7ff7d00df000 ParentCid: 0f34 DirBase: 1fb746000 ObjectTable: ffffc001db6b52c0 HandleCount: 34. Image: echoapp.exe VadRoot ffffe000800cf920 Vads 30 Clone 0 Private 135. Modified 8. Locked 0. DeviceMap ffffc001d83c6e80 Token ffffc001cf5dc050 ElapsedTime 00:00:00.048 UserTime 00:00:00.000 KernelTime 00:00:00.000 QuotaPoolUsage[PagedPool] 33824 QuotaPoolUsage[NonPagedPool] 4464 Working Set Sizes (now,min,max) (681, 50, 345) (2724KB, 200KB, 1380KB) PeakWorkingSetSize 651 VirtualSize 16 Mb PeakVirtualSize 16 Mb PageFaultCount 686 MemoryPriority BACKGROUND BasePriority 8 CommitCharge 138 THREAD ffffe000809a0880 Cid 0b28.1158 Teb: 00007ff7d00dd000 Win32Thread: 0000000000000000 RUNNING on processor 0
Verwenden Sie den Befehl
!process 0 0
, um die Prozessadresse von zwei zusammenhängenden Prozessen zu ermitteln, und zeichnen Sie diese Prozessadresse hier auf.Cmd.exe: ____________________________________________________________
EchoApp.exe: _______________________________________________________
0: kd> !process 0 0 … PROCESS ffffe0007bbde900 SessionId: 1 Cid: 0f34 Peb: 7ff72dfa7000 ParentCid: 0c64 DirBase: 19c5fa000 ObjectTable: ffffc001d8c2f300 HandleCount: 31. Image: cmd.exe … PROCESS ffffe0008096c900 SessionId: 1 Cid: 0b28 Peb: 7ff7d00df000 ParentCid: 0f34 DirBase: 1fb746000 ObjectTable: ffffc001db6b52c0 HandleCount: 34. Image: echoapp.exe …
Sie können alternativ
!process 0 17
verwenden, um detaillierte Informationen über jeden Prozess anzuzeigen. Die Ausgabe dieses Befehls kann sehr umfangreich sein. Die Ausgabe kann mit der Tastenkombination Strg+F durchsucht werden.Verwenden Sie den Befehl
!process
, um Prozessinformationen für beide Prozesse auf Ihrem Computer aufzulisten. Geben Sie die Prozessadresse aus Ihrer!process 0 0
-Ausgabe an, nicht die in diesem Beispiel gezeigte Adresse.Diese Beispielausgabe bezieht sich auf die Prozess-ID cmd.exe, die zuvor aufgezeichnet wurde. Der Imagename für diese Prozess-ID lautet cmd.exe.
0: kd> !process ffffe0007bbde900 PROCESS ffffe0007bbde900 SessionId: 1 Cid: 0f34 Peb: 7ff72dfa7000 ParentCid: 0c64 DirBase: 19c5fa000 ObjectTable: ffffc001d8c2f300 HandleCount: 31. Image: cmd.exe VadRoot ffffe0007bb8e7b0 Vads 25 Clone 0 Private 117. Modified 20. Locked 0. DeviceMap ffffc001d83c6e80 Token ffffc001d8c48050 ElapsedTime 21:33:05.840 UserTime 00:00:00.000 KernelTime 00:00:00.000 QuotaPoolUsage[PagedPool] 24656 QuotaPoolUsage[NonPagedPool] 3184 Working Set Sizes (now,min,max) (261, 50, 345) (1044KB, 200KB, 1380KB) PeakWorkingSetSize 616 VirtualSize 2097164 Mb PeakVirtualSize 2097165 Mb PageFaultCount 823 MemoryPriority FOREGROUND BasePriority 8 CommitCharge 381 THREAD ffffe0007cf34880 Cid 0f34.0f1c Teb: 00007ff72dfae000 Win32Thread: 0000000000000000 WAIT: (UserRequest) UserMode Non-Alertable ffffe0008096c900 ProcessObject Not impersonating ...
Diese Beispielausgabe bezieht sich auf die Prozess-ID echoapp.exe, die zuvor aufgezeichnet wurde.
0: kd> !process ffffe0008096c900 PROCESS ffffe0008096c900 SessionId: 1 Cid: 0b28 Peb: 7ff7d00df000 ParentCid: 0f34 DirBase: 1fb746000 ObjectTable: ffffc001db6b52c0 HandleCount: 34. Image: echoapp.exe VadRoot ffffe000800cf920 Vads 30 Clone 0 Private 135. Modified 8. Locked 0. DeviceMap ffffc001d83c6e80 Token ffffc001cf5dc050 ElapsedTime 00:00:00.048 UserTime 00:00:00.000 KernelTime 00:00:00.000 QuotaPoolUsage[PagedPool] 33824 QuotaPoolUsage[NonPagedPool] 4464 Working Set Sizes (now,min,max) (681, 50, 345) (2724KB, 200KB, 1380KB) PeakWorkingSetSize 651 VirtualSize 16 Mb PeakVirtualSize 16 Mb PageFaultCount 686 MemoryPriority BACKGROUND BasePriority 8 CommitCharge 138 THREAD ffffe000809a0880 Cid 0b28.1158 Teb: 00007ff7d00dd000 Win32Thread: 0000000000000000 RUNNING on processor 0 IRP List: ffffe0007bc5be10: (0006,01f0) Flags: 00060a30 Mdl: 00000000 Not impersonating ...
Notieren Sie hier die erste Thread-Adresse, die mit den beiden Prozessen verbunden ist.
Cmd.exe: ____________________________________________________
EchoApp.exe: _________________________________________________
Verwenden Sie den Befehl
!Thread
, um Informationen über den aktuellen Thread anzuzeigen.0: kd> !Thread THREAD ffffe000809a0880 Cid 0b28.1158 Teb: 00007ff7d00dd000 Win32Thread: 0000000000000000 RUNNING on processor 0 IRP List: ffffe0007bc5be10: (0006,01f0) Flags: 00060a30 Mdl: 00000000 Not impersonating DeviceMap ffffc001d83c6e80 Owning Process ffffe0008096c900 Image: echoapp.exe Attached Process N/A Image: N/A ...
Wie erwartet, ist der aktuelle Thread der Thread, der mit echoapp.exe verbunden ist, und er befindet sich in einem laufenden Zustand.
Verwenden Sie den Befehl
!Thread
, um Informationen über den mit dem Prozess cmd.exe verbundenen Thread anzuzeigen. Geben Sie die Thread-Adresse an, die Sie zuvor aufgezeichnet haben.0: kd> !Thread ffffe0007cf34880 THREAD ffffe0007cf34880 Cid 0f34.0f1c Teb: 00007ff72dfae000 Win32Thread: 0000000000000000 WAIT: (UserRequest) UserMode Non-Alertable ffffe0008096c900 ProcessObject Not impersonating DeviceMap ffffc001d83c6e80 Owning Process ffffe0007bbde900 Image: cmd.exe Attached Process N/A Image: N/A Wait Start TickCount 4134621 Ticks: 0 Context Switch Count 4056 IdealProcessor: 0 UserTime 00:00:00.000 KernelTime 00:00:01.421 Win32 Start Address 0x00007ff72e9d6e20 Stack Init ffffd0015551dc90 Current ffffd0015551d760 Base ffffd0015551e000 Limit ffffd00155518000 Call 0 Priority 14 BasePriority 8 UnusualBoost 3 ForegroundBoost 2 IoPriority 2 PagePriority 5 Child-SP RetAddr : Args to Child : Call Site ffffd001`5551d7a0 fffff801`eed184fe : fffff801`eef81180 ffffe000`7cf34880 00000000`fffffffe 00000000`fffffffe : nt!KiSwapContext+0x76 [d:\9142\minkernel\ntos\ke\amd64\ctxswap.asm @ 109] ffffd001`5551d8e0 fffff801`eed17f79 : ffff03a5`ca56a3c8 000000de`b6a6e990 000000de`b6a6e990 00007ff7`d00df000 : nt!KiSwapThread+0x14e [d:\9142\minkernel\ntos\ke\thredsup.c @ 6347] ffffd001`5551d980 fffff801`eecea340 : ffffd001`5551da18 00000000`00000000 00000000`00000000 00000000`00000388 : nt!KiCommitThreadWait+0x129 [d:\9142\minkernel\ntos\ke\waitsup.c @ 619] ...
Dieser Thread ist mit cmd.exe verbunden und befindet sich in einem Wartezustand.
Geben Sie die Thread-Adresse des wartenden CMD.exe Threads an, um den Kontext zu diesem wartenden Thread zu ändern.
0: kd> .Thread ffffe0007cf34880 Implicit thread is now ffffe000`7cf34880
Verwenden Sie den Befehl
k
, um den mit dem wartenden Thread verbundenen Aufrufstapel anzuzeigen.0: kd> k *** Stack trace for last set context - .thread/.cxr resets it # Child-SP RetAddr Call Site 00 ffffd001`5551d7a0 fffff801`eed184fe nt!KiSwapContext+0x76 [d:\9142\minkernel\ntos\ke\amd64\ctxswap.asm @ 109] 01 ffffd001`5551d8e0 fffff801`eed17f79 nt!KiSwapThread+0x14e [d:\9142\minkernel\ntos\ke\thredsup.c @ 6347] 02 ffffd001`5551d980 fffff801`eecea340 nt!KiCommitThreadWait+0x129 [d:\9142\minkernel\ntos\ke\waitsup.c @ 619] 03 ffffd001`5551da00 fffff801`ef02e642 nt!KeWaitForSingleObject+0x2c0 [d:\9142\minkernel\ntos\ke\wait.c @ 683] ...
Aufrufstapel-Elemente wie
KiCommitThreadWait
zeigen an, dass dieser Thread nicht wie erwartet läuft.
Weitere Informationen über Threads und Prozesse finden Sie in den folgenden Verweisen:
IRQL, Register und Beendigung der WinDbg-Sitzung
In diesem Abschnitt werden die Unterbrechungsanforderungsebene (IRQL) und der Inhalt der Register angezeigt.
Ansicht des gespeicherten IRQL
Der IRQL wird verwendet, um die Priorität der Interrupt-Bearbeitung zu verwalten. Jeder Prozessor hat eine IRQL-Einstellung, die Threads erhöhen oder senken können. Interrupts, die bei oder unterhalb der IRQL-Einstellung des Prozessors auftreten, werden maskiert und stören den laufenden Betrieb nicht. Interrupts, die oberhalb der IRQL-Einstellung des Prozessors auftreten, haben Vorrang vor der aktuellen Operation.
Auf dem Hostsystem zeigt die Erweiterung !irql den IRQL auf dem aktuellen Prozessor des Zielcomputers an, bevor der Debugger-Break auftrat. Wenn der Zielcomputer in den Debugger wechselt, ändert sich der IRQL, aber der IRQL, der kurz vor dem Debugger-Break wirksam war, wird gespeichert und von !irql
angezeigt.
0: kd> !irql
Debugger saved IRQL for processor 0x0 -- 2 (DISPATCH_LEVEL)
Ansicht der Register
Zeigen Sie auf dem Hostsystem den Inhalt der Register für den aktuellen Thread auf dem aktuellen Prozessor an, indem Sie den Befehl r (Registers) verwenden.
0: kd> r
rax=000000000000c301 rbx=ffffe00173eed880 rcx=0000000000000001
rdx=000000d800000000 rsi=ffffe00173eed8e0 rdi=ffffe00173eed8f0
rip=fffff803bb757020 rsp=ffffd001f01f8988 rbp=ffffe00173f0b620
r8=000000000000003e r9=ffffe00167a4a000 r10=000000000000001e
r11=ffffd001f01f88f8 r12=0000000000000000 r13=ffffd001f01efdc0
r14=0000000000000001 r15=0000000000000000
iopl=0 nv up ei pl nz na pe nc
cs=0010 ss=0018 ds=002b es=002b fs=0053 gs=002b efl=00000202
nt!DbgBreakPointWithStatus:
fffff803`bb757020 cc int 3
Alternativ können Sie den Inhalt der Register anzeigen, indem Sie View>Registers wählen. Weitere Informationen finden Sie unter r (Registers).
Die Anzeige der Registerinhalte kann bei der schrittweisen Ausführung von Assemblercode und in anderen Szenarien hilfreich sein. Weitere Informationen zur Assembler-Disassemblierung finden Sie unter Annotated x86 Disassembly und Annotated x64 disassembly.
Informationen zum Inhalt des Registers finden Sie unter x86-Architektur und x64-Architektur.
Beenden der WinDbg-Sitzung
Wenn Sie den Debugger angeschlossen lassen, aber am Ziel arbeiten wollen, löschen Sie alle Haltepunkte mit bc *
, damit der Zielcomputer nicht versucht, eine Verbindung zum Debugger des Host-Computers herzustellen. Verwenden Sie dann den Befehl g
, um den Zielcomputer wieder zum Laufen zu bringen.
Um die Debugging-Sitzung zu beenden, rufen Sie auf dem Hostsystem den Debugger auf und geben den Befehl qd
(Quit and Detach) ein oder wählen Sie Stop Debugging aus dem Menü.
0: kd> qd
Weitere Informationen finden Sie unter Beenden einer Debugging-Sitzung in WinDbg.
Ressourcen zum Debuggen unter Windows
Weitere Informationen finden Sie unter Windows Debugging. Einige dieser Bücher verwenden in ihren Beispielen frühere Versionen von Windows wie Windows Vista, aber die besprochenen Konzepte sind auf die meisten Versionen von Windows anwendbar.
Bücher
- Erweitertes Windows Debugging von Mario Hewardt und Daniel Pravat
- Debugging unter Windows: Ein praktisches Handbuch zu Debugging- und Tracing-Strategien in Windows® von Tarik Soulami
- Windows Internals von Pavel Yosifovich, Alex Ionescu, Mark Russinovich und David Solomon
Video
Anbieter von Schulungen
Weitere Informationen
Feedback
https://aka.ms/ContentUserFeedback.
Bald verfügbar: Im Laufe des Jahres 2024 werden wir GitHub-Issues stufenweise als Feedbackmechanismus für Inhalte abbauen und durch ein neues Feedbacksystem ersetzen. Weitere Informationen finden Sie unterFeedback senden und anzeigen für