Verwenden des richtigen Haltepunkttyps
In diesem Artikel wird gezeigt, wie Sie verschiedene Arten von Haltepunkten in Visual Studio verwenden, um die Debuggingeffizienz zu verbessern. Es behandelt verschiedene Szenarien, in denen Haltepunkte angewendet werden können, z. B. Anhalten der Codeausführung, Protokollierung von Informationen und Verfolgen von Änderungen in den Zuständen von Variablen. In diesem Artikel wird erläutert, wie bedingte Haltepunkte, Ablaufverfolgungspunkte, Datenhaltepunkte, abhängige Haltepunkte und temporäre Haltepunkte festgelegt werden. Sie enthält auch detaillierte Anweisungen zum Festlegen von Funktions-Haltepunkten. Dieses Handbuch ist für Entwickler wichtig, die Haltepunkte für ein effektives Debuggen in Visual Studio nutzen möchten.
Wenn Sie mit der Verwendung von Haltepunkten in Visual Studio nicht vertraut sind, lesen Sie Erste Schritte mit Haltepunkten, bevor Sie diesen Artikel durchgehen.
Um die beste Erfahrung mit dieser Dokumentation zu erzielen, wählen Sie ihre bevorzugte Entwicklungssprache oder Laufzeit aus der Liste oben im Artikel aus.
Drehbücher
Die folgende Tabelle enthält allgemeine Debugszenarien für Haltepunkte und den empfohlenen Haltepunkttyp für das Szenario.
Szenario | Beschreibung |
---|---|
Wie kann ich die Ausführung von Code anhalten, um eine Codezeile zu prüfen, die einen Fehler enthalten kann? | Legen Sie einen Haltepunkt fest. Weitere Informationen finden Sie unter Erste Schritte mit Haltepunkten. |
Hat meine Variable einen unerwarteten Wert? Oder möchte ich meine App prüfen, wenn sie einen bestimmten Zustand erreicht? | Versuchen Sie einen bedingten Haltepunkt, um zu steuern, wo und wann ein Haltepunkt mithilfe der bedingten Logik aktiviert wird. Klicken Sie mit der rechten Maustaste auf einen Haltepunkt, um Bedingungen hinzuzufügen. Legen Sie die Bedingung auf "true" fest, wenn die Variable dem unerwarteten Wert entspricht. Weitere Informationen finden Sie unter Haltepunktbedingungen. |
Wie protokolliere ich Informationen unter konfigurierbaren Bedingungen im Ausgabefenster, ohne meinen Code zu ändern oder zu beenden? | Mit Ablaufverfolgungspunkten können Sie Informationen im Ausgabefenster protokollieren. Hierfür können Sie Bedingungen konfigurieren, sodass der Code nicht geändert oder angehalten werden muss. Weitere Informationen finden Sie unter Verwenden von Ablaufverfolgungspunkten im Visual Studio-Debugger. |
Wie kann ich feststellen, wann sich der Wert meiner Variablen ändert? | Legen Sie für C++ einen Datentrennpunktfest. Für Apps, die .NET Core 3 und höher verwenden, können Sie auch einen Datenhaltepunkt festlegen. Andernfalls können Sie nur für C# und F# eine Objekt-ID mit einem bedingten Haltepunkt nachverfolgen. |
Wie kann ich die Ausführung nur unterbrechen, wenn ein anderer Haltepunkt ausgelöst wird? | Legen Sie einen abhängigen Haltepunkt fest, der die Ausführung nur unterbricht, wenn ein anderer Haltepunkt zuerst getroffen wird. Weitere Informationen finden Sie unter Abhängiger Haltepunkt. |
Kann ich nur einmal einen Haltepunkt auslösen? | Legen Sie einen temporären Haltepunkt fest, mit dem Sie den Code nur einmal unterbrechen können. Weitere Informationen finden Sie unter Temporärer Haltepunkt. |
Kann ich Code in einer Schleife bei einer bestimmten Iteration anhalten? | Legen Sie einen abhängigen Haltepunkt fest, der die Ausführung nur unterbricht, wenn ein anderer Haltepunkt zuerst getroffen wird. Weitere Informationen finden Sie unter Trefferanzahl. |
Kann ich Code am Anfang einer Funktion anhalten, wenn ich den Funktionsnamen kennt, aber nicht seine Position? | Hierfür können Sie einen Funktionsbreakpoint verwenden. Weitere Informationen finden Sie unter Festlegen von Funktions-Haltepunkten. |
Kann ich Code am Anfang mehrerer Funktionen mit demselben Namen anhalten? | Wenn Sie über mehrere Funktionen mit demselben Namen verfügen (überladene Funktionen oder Funktionen in verschiedenen Projekten), können Sie einen Funktionstrennpunktverwenden. |
Haltepunktaktionen und Ablaufverfolgungspunkte
Beim Ablaufverfolgungspunkt handelt es sich um einen Haltepunkt, der eine Meldung im Fenster Ausgabe ausgibt. Ein Ablaufverfolgungspunkt kann wie eine temporäre Ablaufverfolgungsanweisung in der Programmiersprache wirken und die Ausführung von Code nicht anhalten. Sie erstellen einen Ablaufverfolgungspunkt, indem Sie eine spezielle Aktion im Fenster Haltepunkteinstellungen festlegen. Eine detaillierte Anleitung finden Sie unter Protokollinformationen im Ausgabefenster mithilfe von Ablaufverfolgungspunkten in Visual Studio.
Haltepunktbedingungen
Sie können steuern, wann und wo ein Haltepunkt ausgeführt wird, indem Sie Bedingungen festlegen. Die Bedingung kann ein beliebiger gültiger Ausdruck sein, den der Debugger erkennt. (Weitere Informationen zu gültigen Ausdrücken finden Sie unter Ausdrücke im Debugger.)
So legen Sie eine Haltepunktbedingung fest:
Klicken Sie mit der rechten Maustaste auf das Haltepunktsymbol, und wählen Sie Bedingungen aus (oder drücken Sie Alt + F9, C). Oder zeigen Sie mit dem Mauszeiger auf das Haltepunktsymbol, wählen Sie das Symbol Einstellungen aus, und wählen Sie dann Bedingungen im Fenster Haltepunkteinstellungen aus.
Sie können auch mit der rechten Maustaste auf den linken Rand neben einer Codezeile klicken und "Bedingten Haltepunkt einfügen" aus dem Kontextmenü auswählen, um einen neuen bedingten Haltepunkt festzulegen.
Sie können Bedingungen auch im Haltepunkt- Fenster festlegen, indem Sie mit der rechten Maustaste auf einen Haltepunkt klicken und Einstellungenauswählen und dann Bedingungen
Klicken Sie im Dropdown auf Bedingter Ausdruck, Trefferanzahl oder Filter und legen Sie den Wert entsprechend fest.
Klicken Sie auf Schließen, oder drücken Sie STRG+EINGABETASTE, um das Fenster Haltepunkteinstellungen zu schließen. Alternativ können Sie im Fenster Haltepunkte auf OK klicken, um das Dialogfeld zu schließen.
Breakpoints, für die Bedingungen festgelegt wurden, werden im Quellcode und im Fenster Haltepunkte mit einem +-Symbol angezeigt.
Erstellen eines bedingten Ausdrucks
Wenn Sie Bedingter Ausdruck auswählen, können Sie zwischen zwei Bedingungen auswählen: Ist True oder Bei Änderung. Wählen Sie ist „True“ aus, um die Ausführung zu unterbrechen, wenn der Ausdruck erfüllt ist. Wenn Sie Bei Änderung auswählen, wird die Ausführung unterbrochen, wenn sich der Wert des Ausdrucks geändert hat.
Im folgenden Beispiel wird der Haltepunkt nur erreicht, wenn der Wert von testInt
4ist:
Im folgenden Beispiel wird der Haltepunkt nur erreicht, wenn sich der Wert von testInt
ändert:
Wenn Sie eine Haltepunktbedingung mit ungültiger Syntax festlegen, wird eine Warnmeldung angezeigt. Wenn Sie eine Haltepunktbedingung mit gültiger Syntax, aber ungültiger Semantik angeben, wird beim ersten Treffer des Haltepunkts eine Warnmeldung angezeigt. In beiden Fällen unterbricht der Debugger die Ausführung beim Erreichen des ungültigen Breakpoints. Der Haltepunkt wird nur übersprungen, wenn die Bedingung gültig ist und mit false
bewertet wird.
Anmerkung
Für das Feld Bei Änderung betrachtet der Debugger die erste Auswertung nicht als Änderung. Der Breakpoint wird also bei der ersten Auswertung nicht beachtet.
Verwenden von Objekt-IDs in bedingten Ausdrücken (nur C# und F#)
Es gibt Zeiten, in denen Sie das Verhalten eines bestimmten Objekts beobachten möchten. Sie können beispielsweise herausfinden, warum ein Objekt mehrmals in eine Auflistung eingefügt wurde. In C# und F# können Sie Objekt-IDs für bestimmte Instanzen von Verweistypen erstellen und in Haltepunktbedingungen verwenden. Die Objekt-ID wird von den Debugdiensten der Common Language Runtime (CLR) generiert und dem Objekt zugeordnet.
So erstellen Sie eine Objekt-ID:
Legen Sie im Code einen Haltepunkt fest, nachdem das Objekt erstellt wurde.
Starten Sie das Debuggen, und wenn die Ausführung am Haltepunkt angehalten wird, wählen Sie Debug>Windows>Locals (oder drücken Sie STRG + ALT + V, L), um das fenster Locals zu öffnen.
Suchen Sie im Fenster Lokale Variablen nach der spezifischen Objektinstanz, klicken Sie mit der rechten Maustaste darauf, und klicken Sie dann auf Objekt-ID erstellen.
Es sollte eine $ und eine Zahl im Fenster Lokale angezeigt werden. Dies ist die Objekt-ID.
Fügen Sie einen neuen Haltepunkt an der Stelle hinzu, die Sie untersuchen möchten; zum Beispiel, wenn das Objekt der Sammlung hinzugefügt werden soll. Klicken Sie mit der rechten Maustaste auf den Haltepunkt und wählen Sie Bedingungen aus.
Verwenden Sie die Objekt-ID im Feld Bedingter Ausdruck. Wenn beispielsweise die Variable
item
das Objekt ist, das der Auflistung hinzugefügt werden soll, wählen Sie Ist true aus, und geben Sie Element ein == $<n>, wobei <n> die Objekt-ID-Nummer ist.Die Ausführung wird an dem Punkt abgebrochen, an dem das Objekt der Auflistung hinzugefügt werden soll.
Um die Objekt-ID zu löschen, klicken Sie im Fenster Lokal mit der rechten Maustaste auf die Variable, und wählen Sie Objekt-ID löschenaus.
Anmerkung
Objekt-IDs erstellen Weak-Verweise und verhindern nicht, dass das Objekt in die Garbage Collection aufgenommen wird. Sie sind nur für die aktuelle Debugsitzung gültig.
Festlegen einer Trefferanzahlbedingung
Wenn Sie vermuten, dass eine Schleife im Code nach einer bestimmten Anzahl von Iterationen fehlschlägt, können Sie einen Haltepunkt festlegen, um die Ausführung nach dieser Anzahl von Treffern zu beenden, anstatt wiederholt F5- drücken zu müssen, um diese Iteration zu erreichen.
Klicken Sie im Fenster Haltepunkteinstellungen unter Bedingungen auf die Option Trefferanzahl und geben Sie dann die Anzahl an Iterationen an. Im folgenden Beispiel wird der Breakpoint so festgelegt, dass er bei jeder weiteren Iteration beachtet wird:
Festlegen einer Filterbedingung
Sie können einen Haltepunkt so einschränken, dass dieser nur auf bestimmten Geräten oder in angegebenen Prozesse und Threads aktiviert wird.
Klicken Sie im Fenster Haltepunkteinstellungen unter Bedingungen auf Filter, und geben Sie dann mindestens einen der folgenden Ausdrücke ein:
- MachineName = "name"
- ProcessId = Wert
- ProcessName = "name"
- ThreadId = value
- ThreadName = "name"
Schließen Sie Zeichenfolgenwerte in doppelte Anführungszeichen ein. Sie können Klauseln mithilfe von &
(AND), ||
(OR), !
(NOT) und Klammern kombinieren.
Festlegen von Funktions-Haltepunkten
Sie können die Ausführung unterbrechen, wenn eine Funktion aufgerufen wird. Dies ist beispielsweise hilfreich, wenn Sie den Funktionsnamen kennen, aber nicht dessen Position. Es ist auch hilfreich, wenn Sie Funktionen mit demselben Namen haben und sie alle unterbrechen möchten (z. B. überladene Funktionen oder Funktionen in verschiedenen Projekten).
So legen Sie einen Funktionstrennpunkt fest:
Wählen Sie Debuggen>Neuer Haltepunkt>Funktionshaltepunkt aus, oder drücken Sie STRG + K, B.
Alternativ können Sie im Fenster Haltepunkte auch auf Neu > Funktionshaltepunkt klicken.
Geben Sie im Dialogfeld Neuer Funktionshaltepunkt den Funktionsname in das Feld Funktionsname ein.
So schränken Sie die Funktionsspezifikation ein:
Verwenden Sie den vollqualifizierten Funktionsnamen.
Beispiel:
Namespace1.ClassX.MethodA()
Fügen Sie die Parametertypen einer überladenen Funktion hinzu.
Beispiel:
MethodA(int, string)
Verwenden Sie das Symbol "!", um das Modul anzugeben.
Beispiel:
App1.dll!MethodA
Verwenden Sie den Kontextoperator in systemeigenem C++.
{function, , [module]} [+<line offset from start of method>]
Beispiel:
{MethodA, , App1.dll}+2
Wählen Sie im Dropdownmenü Sprache die Sprache der Funktion aus.
Wählen Sie OKaus.
Festlegen eines Funktionstrennpunkts mithilfe einer Speicheradresse (nur systemeigenes C++)
Sie können die Adresse eines Objekts verwenden, um einen Funktionstrennpunkt für eine Methode festzulegen, die von einer bestimmten Instanz einer Klasse aufgerufen wird. Bei einem adressierbaren Objekt vom Typ my_class
können Sie z. B. einen Funktionsunterbrechungspunkt für die my_method
-Methode festlegen, die von der Instanz aufgerufen wird.
Legen Sie einen Haltepunkt an einer beliebigen Stelle fest, nachdem die Instanz der Klasse instanziiert wurde.
Suchen Sie die Adresse der Instanz (z. B.
0xcccccccc
).Wählen Sie Debuggen>Neuer Haltepunkt>Funktionshaltepunkt aus, oder drücken Sie STRG + K, B.
Fügen Sie folgendes zum Feld Funktionsname hinzu, und wählen Sie C++- Sprache aus.
((my_class *) 0xcccccccc)->my_method
Festlegen von Datenhaltepunkten (.NET Core 3.x oder .NET 5+)
Datenhaltepunkte unterbrechen die Ausführung, wenn sich die Eigenschaft eines bestimmten Objekts ändert.
So setzen Sie einen Daten-Breakpoint:
Starten Sie das Debuggen in einem .NET Core- oder .NET 5+Projekt, und warten Sie, bis ein Breakpoint erreicht wird.
Klicken Sie in einem der Fenster Auto, Überwachung oder Lokale Variablen mit der rechten Maustaste auf eine Eigenschaft und klicken Sie dann im Kontextmenü auf die Option Bei Wertänderungen unterbrechen.
Datenhaltepunkte für .NET Core und .NET 5+ funktionieren nicht für:
- Eigenschaften, die im QuickInfo-, Lokale Variablen-, Auto- oder Überwachungsfenster nicht aufgeklappt werden können
- Statische Variablen
- Klassen mit dem DebuggerTypeProxy-Attribut
- Felder innerhalb von Strukturen
Die maximale festzulegende Anzahl finden Sie unter Hardwaregrenzwerte für Datenbreakpoints.
Festlegen von Datenzugriffspunkten (nur C++ in nativer Form)
Datenhaltepunkte unterbrechen die Ausführung, wenn sich ein in einer angegebenen Speicheradresse gespeicherter Wert ändert. Wenn der Wert gelesen, aber nicht geändert wird, wird die Ausführung nicht abgebrochen.
So legen Sie einen Datenbreakpoint fest:
Starten Sie in einem C++-Projekt das Debuggen, und warten Sie, bis ein Haltepunkt erreicht ist. Wählen Sie im Menü Debuggen die Option Neuer Haltepunkt>Datenhaltepunkt aus.
Alternativ können Sie im Fenster Haltepunkte auf Neu > Datenhaltepunkt klicken, oder mit der rechten Maustaste auf ein Element in einem der Fenster Auto, Überwachung oder Lokale Variablen klicken und dann im Kontextmenü auf die Option Bei Wertänderungen unterbrechen klicken.
Geben Sie im Feld Adresse eine Speicheradresse oder einen Ausdruck ein, der als Speicheradresse ausgewertet wird. Geben Sie z. B.
&avar
ein, um zu unterbrechen, wenn sich der Inhalt der Variablen ändertavar
.Wählen Sie im Dropdownmenü Byteanzahl die Anzahl der Bytes aus, die der Debugger überwachen soll. Wenn Sie z. B. 4auswählen, überwacht der Debugger die vier Bytes, beginnend bei
&avar
, und unterbricht, wenn sich einer dieser Bytewerte ändert.
Daten-Breakpoints funktionieren unter den folgenden Umständen nicht:
- Ein Prozess, der nicht gedebuggt wird, schreibt an den Speicherort.
- Der Speicherort wird von zwei oder mehr Prozessen geteilt.
- Der Speicherort wird innerhalb des Kernels aktualisiert. Wenn beispielsweise Speicher an die 32-Bit-Windows-
ReadFile
-Funktion übergeben wird, erfolgt die Aktualisierung des Speichers im Kernelmodus, sodass der Debugger beim Update nicht unterbrochen wird. - In Szenarios, in denen der Überwachungsausdruck eine Größe von 4 Bytes auf einer 32-Bit-Hardware bzw. von 8 Bytes auf einer 64-Bit-Hardware überschreitet. Dies ist eine Einschränkung der x86-Architektur.
Anmerkung
Datentrennpunkte sind von bestimmten Speicheradressen abhängig. Die Adresse einer Variablen ändert sich von einer Debugsitzung zur nächsten, sodass Datenhaltepunkte am Ende jeder Debugsitzung automatisch deaktiviert werden.
Wenn Sie einen Datenhaltepunkt für eine lokale Variable festlegen, bleibt der Haltepunkt aktiviert, wenn die Funktion endet, die Speicheradresse jedoch nicht mehr anwendbar ist, sodass das Verhalten des Haltepunkts unvorhersehbar ist. Wenn Sie einen Datenhaltepunkt für eine lokale Variable festlegen, sollten Sie den Haltepunkt löschen oder deaktivieren, bevor die Funktion endet.
Hardwarebeschränkungen für Datenbreakpoints
Der Windows-Kernel und die zugrunde liegende Hardware weisen beim Festlegen von Datenhaltepunkten die folgenden Grenzwerte auf. Der Grenzwert bezieht sich auf die maximale Anzahl von Datenhaltepunkten, die Sie festlegen können.
Prozessorarchitektur | Grenzwert für Datenunterbrechungspunkte |
---|---|
x64 und x86 | 4 |
ARM64 | 2 |
ARM | 1 |
Festlegen eines abhängigen Haltepunkts
Abhängige Haltepunkte unterbrechen die Ausführung nur dann, wenn zuerst ein anderer Haltepunkt erreicht wird. In einem komplexen Szenario, z. B. beim Debuggen einer Multithreadanwendung, können Sie die zusätzlichen Haltepunkte konfigurieren, nachdem ein anderer Haltepunkt erstmals erreicht wurde. Dies kann das Debuggen von Code in gängigen Pfaden wie spielschleifen oder einer Hilfs-API erheblich vereinfachen, da ein Haltepunkt in diesen Funktionen so konfiguriert werden kann, dass er nur aktiviert werden kann, wenn die Funktion aus einem bestimmten Teil Ihrer Anwendung aufgerufen wird.
So legen Sie einen abhängigen Haltepunkt fest:
Zeigen Sie auf das Haltepunktsymbol, wählen Sie das Symbol Einstellungen aus, und wählen Sie dann im Fenster „Haltepunkteinstellungen“ die Option Nur aktivieren, wenn folgender Haltepunkt erreicht wird aus.
Wählen Sie in der Dropdownliste den erforderlichen Haltepunkt aus, von dem Ihr aktueller Haltepunkt abhängig sein soll.
Wählen Sie Schließen Sie aus, oder drücken Sie STRG+EINGABETASTE, um das Fenster "Haltepunkteinstellungen" zu schließen. Oder wählen Sie im Fenster "Haltepunkte" OK aus, um das Dialogfeld zu schließen.
Sie können auch das Rechtsklick-Kontextmenü verwenden, um den bedingten Haltepunkt festzulegen.
Klicken Sie mit der rechten Maustaste auf den linken Rand neben einer Codezeile und wählen Sie im Kontextmenü Abhängigen Haltepunkt einfügen aus.
- Abhängige Haltepunkte funktionieren nicht, wenn nur ein einzelner Haltepunkt in Ihrer Anwendung vorhanden ist.
- Abhängige Haltepunkte werden in einen normalen Zeilenhaltepunkt konvertiert, wenn der erforderliche Haltepunkt gelöscht wird.
Festlegen eines temporären Haltepunkts
Mit diesem Haltepunkt können Sie den Code nur einmal unterbrechen. Beim Debuggen hält der Visual Studio-Debugger die laufende Anwendung nur einmal bei diesem Haltepunkt an und entfernt ihn, gleich nachdem er erreicht wurde.
So legen Sie einen temporären Haltepunkt fest:
Zeigen Sie auf das Haltepunktsymbol, wählen Sie das Symbol Einstellungen aus, und wählen Sie dann im Fenster „Haltepunkteinstellungen“ die Option Haltepunkt nach Erreichen entfernen aus.
Wählen Sie Schließen Sie aus, oder drücken Sie STRG+EINGABETASTE, um das Fenster "Haltepunkteinstellungen" zu schließen. Oder wählen Sie im Fenster "Haltepunkte" OK aus, um das Dialogfeld zu schließen.
Sie können auch das Kontextmenü mit der rechten Maustaste verwenden, um den temporären Haltepunkt festzulegen.
Klicken Sie mit der rechten Maustaste auf den linken Rand neben einer Codezeile, und wählen Sie im Kontextmenü Temporären Haltepunkt einfügen aus.
Drücken Sie alternativ die Tastenkombination F9+UMSCHALT+ALT, T und setzen Sie den temporären Haltepunkt in der gewünschten Zeile.