Debuggen im Quellmodus

Das Debuggen einer Anwendung ist einfacher, wenn Sie anstelle der zerlegten Binärdateien die Quelle des Codes analysieren können.

WinDbg, CDB und KD können Quellcode beim Debuggen verwenden, wenn die Quellsprache C, C++ oder Assembly ist.

Kompilierungsanforderungen

Um das Quelldebuggen zu verwenden, müssen Sie vom Compiler oder Linker Symboldateien (PDB-Dateien) erstellt werden, wenn die Binärdateien erstellt werden. Diese Symboldateien zeigen dem Debugger an, wie die binären Anweisungen den Quellzeilen entsprechen.

Außerdem muss der Debugger auf die tatsächlichen Quelldateien zugreifen können, da Symboldateien nicht den tatsächlichen Quelltext enthalten.

Wenn dies möglich ist, sollten Compiler und Linker Ihren Code nicht optimieren. Das Debuggen von Quellen und der Zugriff auf lokale Variablen ist schwieriger und manchmal fast unmöglich, wenn der Code optimiert wurde. Wenn Sie das Hilfsprogramm Build als Compiler und Linker verwenden, legen Sie das MSC_OPTIMIZATION Makro auf /Od /Oi fest, um eine Optimierung zu vermeiden.

Suchen der Symboldateien und Quelldateien

Zum Debuggen im Quellmodus muss der Debugger in der Lage sein, die Quelldateien und die Symboldateien zu finden. Weitere Informationen finden Sie unter Quellpfad.

Beginnen des Quelldebuggings

Der Debugger kann Quellinformationen anzeigen, wenn er über die richtigen Symbole und Quelldateien für den Thread verfügt, der gerade debuggt wird.

Wenn Sie eine neue Anwendung im Benutzermodus mithilfe des Debuggers starten, tritt der anfängliche Umbruch auf, wenn Ntdll.dll die Anwendung lädt. Da der Debugger keinen Zugriff auf die Ntdll.dll Quelldateien hat, können Sie derzeit nicht auf Quellinformationen für Ihre Anwendung zugreifen.

Um den Programmzähler an den Anfang der Anwendung zu verschieben, fügen Sie ihrer Binärdatei einen Haltepunkt am Einstiegspunkt hinzu. Geben Sie im Fenster Debuggerbefehl den folgenden Befehl ein.

bp main
g

Die Anwendung wird dann geladen und wird beendet, wenn die Standard-Funktion eingegeben wird. (Natürlich können Sie jeden Einstiegspunkt verwenden, nicht nur Standard.)

Wenn die Anwendung eine Ausnahme auslöst, wird sie in den Debugger eingegliedert. Quellinformationen sind an diesem Punkt verfügbar. Wenn Sie jedoch einen Umbruch mithilfe von STRG+C, STRG+BREAK oder Debuggen | Umbruchbefehl, erstellt der Debugger einen neuen Thread, sodass Der Quellcode nicht angezeigt wird.

Nachdem Sie einen Thread erreicht haben, für den Sie Quelldateien haben, können Sie das Debuggerbefehlsfenster verwenden, um Quelldebuggingbefehle auszuführen. Wenn Sie WinDbg verwenden, wird das Quellfenster angezeigt. Wenn Sie bereits ein Quellfenster geöffnet haben, indem Sie im Menü Datei auf Quelldatei öffnen klicken, erstellt WinDbg in der Regel ein neues Fenster für die Quelle. Sie können das vorherige Fenster schließen, ohne den Debugvorgang zu beeinträchtigen.

Quelldebuggen in der WinDbg-Benutzeroberfläche

Wenn Sie WinDbg verwenden, wird ein Quellfenster angezeigt, sobald sich der Programmindikator im Code befindet, für den der Debugger Quellinformationen enthält.

WinDbg zeigt ein Quellfenster für jede Quelldatei an, die Sie oder WinDbg geöffnet haben. Weitere Informationen zu den Texteigenschaften dieses Fensters finden Sie unter Quellfenster.

Anschließend können Sie ihre Anwendung schrittweise durchlaufen oder an einem Haltepunkt oder an den Cursor ausführen. Weitere Informationen zum Schritt- und Ablaufverfolgungsbefehl finden Sie unter Steuern des Ziels.

Wenn Sie sich im Quellmodus befinden, wird das entsprechende Quellfenster in den Vordergrund verschoben, während Sie Ihre Anwendung durchlaufen. Da es auch Microsoft Windows-Routinen gibt, die während der Ausführung der Anwendung aufgerufen werden, verschiebt der Debugger möglicherweise ein Disassembly-Fenster in den Vordergrund, wenn diese Art von Aufruf erfolgt (da der Debugger keinen Zugriff auf die Quelle für diese Funktionen hat). Wenn der Programmindikator zu bekannten Quelldateien zurückkehrt, wird das entsprechende Quellfenster aktiv.

Während Sie die Anwendung durchlaufen, hebt WinDbg Ihren Standort im Quellfenster und im Fenster Disassembly hervor. Zeilen, an denen Haltepunkte festgelegt werden, werden ebenfalls hervorgehoben. Der Quellcode ist entsprechend der Analyse der Sprache farbig. Wenn das Quellfenster ausgewählt wurde, können Sie mit der Maus auf ein Symbol zeigen, um es auszuwerten. Weitere Informationen zu diesen Features und deren Steuerung finden Sie unter Quell-Windows.

Um den Quellmodus in WinDbg zu aktivieren, verwenden Sie den Befehl l+t, klicken Sie im Debugmenü auf Quellmodus, oder klicken Sie auf die Schaltfläche Quellmodus ein. Wenn der Quellmodus aktiv ist, wird der ASM-Indikator auf der status leiste nicht verfügbar angezeigt.

Sie können die Werte beliebiger lokaler Variablen anzeigen oder ändern, wenn Sie eine Funktion im Quellmodus durchlaufen. Weitere Informationen finden Sie unter Lese- und Schreibspeicher.

Quelldebuggen im Debuggerbefehlsfenster

Wenn Sie CDB verwenden, verfügen Sie nicht über ein separates Quellfenster. Sie können ihren Fortschritt jedoch weiterhin anzeigen, während Sie die Quelle durchlaufen.

Bevor Sie das Quelldebuggen in CDB durchführen können, müssen Sie Quellzeilensymbole laden, indem Sie den Befehl .lines (Quellcodezeilenunterstützung umschalten) ausgeben oder den Debugger mit der Befehlszeilenoption -lines starten.

Wenn Sie einen l+t-Befehl ausführen, wird das gesamte Programmschritt jeweils eine Quellzeile nach dem anderen ausgeführt. Verwenden Sie l-t , um jeweils eine Assemblyanweisung zu durchlaufen. Wenn Sie WinDbg verwenden, hat dieser Befehl die gleiche Auswirkung wie das Auswählen oder Deaktivieren des Quellmodus im Menü Debuggen oder die Verwendung der Symbolleistenschaltflächen.

Der Befehl l+s zeigt die aktuelle Quellzeile und Zeilennummer an der Eingabeaufforderung an. Wenn Sie nur die Zeilennummer anzeigen möchten, verwenden Sie stattdessen l+l .

Wenn Sie l+o und l+s verwenden, wird beim Durchlaufen des Programms nur die Quellzeile angezeigt. Der Programmzähler, der Disassemblierungscode und die Registrierungsinformationen sind ausgeblendet. Mit dieser Art von Anzeige können Sie schnell den Code durchlaufen und nichts als die Quelle anzeigen.

Sie können den Befehl lsp (Set Number of Source Lines) verwenden, um genau anzugeben, wie viele Quellzeilen beim Durchlaufen oder Ausführen der Anwendung angezeigt werden.

Die folgende Befehlssequenz ist eine effektive Möglichkeit, eine Quelldatei zu durchlaufen.

.lines        enable source line information
bp main       set initial breakpoint
l+t           stepping will be done by source line
l+s           source lines will be displayed at prompt
g             run program until "main" is entered
pr            execute one source line, and toggle register display off
p             execute one source line 

Da ENTER den letzten Befehl wiederholt, können Sie jetzt die Anwendung mithilfe der EINGABETASTE schrittweise durchlaufen. Jeder Schritt bewirkt, dass der Quellzeilen-, Speicheroffset- und Assemblycode angezeigt wird.

Weitere Informationen zum Interpretieren der Disassemblierungsanzeige finden Sie unter Debuggen im Assemblymodus.

Wenn der Assemblycode angezeigt wird, wird jeder Speicherspeicherort, auf den zugegriffen wird, am rechten Ende der Zeile angezeigt. Sie können die Befehle d* (Speicher anzeigen) und e* (Werte eingeben) verwenden, um die Werte an diesen Speicherorten anzuzeigen oder zu ändern.

Wenn Sie jede Assemblyanweisung anzeigen müssen, um Offsets oder Speicherinformationen zu bestimmen, verwenden Sie l-t , um Schrittweise Assemblyanweisungen anstelle von Quellzeilen zu verwenden. Die Quellzeileninformationen können weiterhin angezeigt werden. Jede Quellzeile entspricht einer oder mehreren Assemblyanweisungen.

Alle diese Befehle sind in WinDbg und in CDB verfügbar. Sie können die Befehle verwenden, um Die Quellzeileninformationen aus dem Fenster Debuggerbefehl von WinDbg anstatt im Quellfenster anzuzeigen.

Quelllinien und Offsets

Sie können das Quelldebuggen auch mithilfe des Ausdrucksauswerters durchführen, um den Offset zu bestimmen, der einer bestimmten Quellzeile entspricht.

Der folgende Befehl zeigt einen Speicheroffset an.

? `[[module!]filename][:linenumber]` 

Wenn Sie den Dateinamen weglassen, sucht der Debugger nach der Quelldatei, die dem aktuellen Programmindikator entspricht.

Der Debugger liest Zeilennummer als Dezimalzahl, es sei denn, Sie fügen 0x davor hinzu, unabhängig vom aktuellen Standardradix. Wenn Sie zeilennummer weglassen, wird der Ausdruck mit der Anfangsadresse der ausführbaren Datei ausgewertet, die der Quelldatei entspricht.

Diese Syntax wird in CDB nur verstanden, wenn der Befehl .lines oder die Befehlszeilenoption -lines Quellzeilensymbole geladen hat.

Diese Technik ist sehr vielseitig, da Sie sie unabhängig davon verwenden können, wo der Programmzähler zeigt. Mit dieser Technik können Sie beispielsweise Haltepunkte im Voraus festlegen, indem Sie Befehle wie den folgenden verwenden.

bp `source.c:31` 

Weitere Informationen finden Sie unter Quellcodezeilensyntax und Verwenden von Haltepunkten.

Schrittschritt und Ablaufverfolgung im Quellmodus

Beim Debuggen im Quellmodus kann es mehrere Funktionsaufrufe in einer einzelnen Quellzeile geben. Sie können diese Funktionsaufrufe nicht mit den Befehlen p und t trennen.

Im folgenden Befehl wird mit dem t-Befehl beispielsweise getTickCount und printf ausgeführt, während der p-Befehl schritte für beide Funktionsaufrufe ausführt.

printf( "%x\n", GetTickCount() );

Wenn Sie bestimmte Aufrufe während der Ablaufverfolgung in andere Aufrufe ausführen möchten, verwenden Sie .step_filter (Set Step Filter), um anzugeben, welche Aufrufe ausgeführt werden sollen.

Sie können _step_filter verwenden, um Frameworkfunktionen (z. B. Microsoft Foundation-Klassen (MFC) oder ATL-Aufrufe (Active Template Library) herauszufiltern.