Laden...

[Artikel] Debugger: Wie verwende ich den von Visual Studio?

Erstellt von MrSparkle vor 10 Jahren Letzter Beitrag vor 2 Jahren 39.057 Views
MrSparkle Themenstarter:in
5.657 Beiträge seit 2006
vor 10 Jahren
[Artikel] Debugger: Wie verwende ich den von Visual Studio?

Wie verwende ich den Debugger von Visual Studio?

Bugs sind kleine, gemeine  Schädlinge, die sich in unserem Programmcode breitmachen, und ihn daran hindern, korrekt zu funktionieren. Aber wie spürt man einen Bug zwischen tausenden von Programmzeilen auf? Seit dem ersten Bug von 1947 haben findige Menschen dazu beigetragen, dass uns diese Arbeit heute zum großen Teil von einem Programm abgenommen wird: dem Debugger. Und das Beste daran ist, dass er uns sogar in der kostenlosen Express-Version von Visual Studio zur Verfügung steht.

Aber wie verwendet man den Debugger, um einen Fehler aufzuspüren?

In den meisten Fällen macht sich ein Programmfehler dadurch bemerkbar, dass das Programm nicht tut, was es tun soll oder dadurch, dass eine Ausnahme (Exception) ausgelöst wird. In letzterem Fall hat man zwar die Stelle lokalisiert, an der der Fehler seine Auswirkung gezeigt hat, aber noch nicht dessen Ursache. Um an die Fehlerursache zu kommen, müsste man wissen, welche Werte bestimmte Variablen haben. Und es wäre hilfreich, das Programm Schritt für Schritt bzw. Zeile für Zeile auszuführen und zu beobachten, wie sich diese Werte ändern. Damit haben wir bereits die wesentlichen Funktionen des Debuggers in Visual Studio vorweggenommen:


Ein Breakpoint in VisualStudio
Ein Breakpoint in VisualStudio
Haltepunkte (Breakpoints)
Damit man ein Programm Schritt für Schritt durchlaufen kann, muss man es zunächst anhalten bzw. pausieren. Mit einem Rechtsklick auf das Projekt -> Debuggen -> In Neue Instanz springen (Debug -> Step Into new instance) wird das Programm gestartet und an der ersten Anweisung angehalten. Meistens genügt das allerdings nicht, und man möchte direkt in eine bestimmte Methode oder eine bestimmte Schleife springen.

Das Programm wurde an einem Breakpoint angehalten
Das Programm wurde an einem Breakpoint angehalten
Um das Programm an einer beliebigen Stelle im Code anzuhalten, setzt man einen Haltepunkt. Dazu klickt man links neben die entsprechende Programmzeile oder drückt F9. Die Zeile wird dann rot eingefärbt und es erscheint ein roter Punkt (der Halte-"Punkt"). Das Programm wird jetzt immer dann pausiert, wenn diese Codestelle bei der Ausführung erreicht wird.


Die Breakpoint-Bedingung
Die Breakpoint-Bedingung
Bedingte Haltepunkte (Conditional Breakpoints)
In manchen Situationen hat man bereits festgestellt, dass ein Fehler immer nur unter bestimmten Umständen auftritt, z.B. wenn eine Variable i den Wert 0 hat. Damit das Programm auch nur dann angehalten wird, kann man mit der rechten Maustaste auf einen Haltepunkt klicken und im Kontextmenü den Befehl für die Bedingung auswählen. Dort kann man dann z.B. i == 0 eingeben oder (fast) beliebige andere Bedingungen.


Variablenwerte überwachen mit
Variablenwerte überwachen mit "DataTips"
Variablen-Überwachung (Watches)
Während das Programm angehalten ist - beispielsweise durch einen Haltepunkt oder eine Ausnahme (Exception) - kann man einfach mit der Maus über eine Variable fahren. Dann erscheint eine "DataTip" genannte Kurzinfo mit dem Typ und dem Wert der Variablen. Die meisten Fehler lassen sich bereits dadurch aufspüren, da man sehr schnell erkennt, wenn eine Variable einen unerwarteten Wert hat, wie z.B. null. Man kann die Werte übrigens dort auch direkt verändern, indem man doppelt auf den angezeigten Wert klickt.

Die "DataTips" haben einen kleinen Pin, der verhindert, dass sie automatisch wieder geschlossen werden. So kann man sich mehrere Variablen zur gleichen Zeit anschauen.

Das Variablen-Überwachungsfenster
Das Variablen-Überwachungsfenster
Um dabei nicht die Übersicht zu verlieren, gibt es das Überwachungs-Fenster, in dem man beliebige Anweisungen (nicht nur Variablen) eintragen, überwachen und verändern kann. Alternativ dazu kann man im Quellcode eine Anweisung markieren und über "Überwachung hinzufügen" ("Add Watch") im Kontextmenü zum Überwachungsfenster hinzufügen.


Einzelschritt-Debugging (Single Step Debugging)
Hat man sich mit den bisher genannten Möglichkeiten einen Überblick über den aktuellen Zustand des Programms geschaffen, will man oft wissen, welcher Code weiterhin ausgeführt wird, und wie sich dadurch die Werte der Variablen ändern. So kann man genau die Codezeile aufspüren, in der die Fehlerursache liegt (und sie beheben).

Das geht mit der Einzelschritt-Funktion (F11). Dann wird die Programmausführung nach jeder Anweisung wieder unterbrochen und man kann Schritt für Schritt durch das Programm gehen, um den Programmablauf genauestens nachzuvollziehen. Mit F10 kann man Methoden-Aufrufe überspringen, um zu verhindern, dass jede einzelne Anweisung innerhalb einer aufgerufenen Methode ausgeführt wird.

Noch schneller ist es manchmal, einige zusätzliche Haltepunkte an den interessanten Codestellen zu setzen und dann das Programm mit F5 weiter auszuführen. Das Programm wird dann beim ersten Haltepunkt, der erreicht wird, wieder angehalten. So lässt sich gezielt herausfinden, welche Codeblöcke bei der Ausführung durchlaufen werden und in welcher Reihenfolge sie dabei aufgerufen werden.

Die genannten Möglichkeiten des Einzelschritt-Debuggings helfen somit einerseits bei der Überwachung des Programmzustands (z.B. fehlerhafte Werte in Variablen) als auch beim Aufspüren von Fehlern im Programmablauf (z.B. bei fehlerhaften Abbruchbedingungen in Schleifen).


Nächste Anweisung setzen im Kontextmenü
Nächste Anweisung setzen im Kontextmenü
Nächste Anweisung setzen (Set Next Statement)
Um selbst in den Programmablauf einzugreifen, z.B. um eine Funktion ein weiteres Mal aufzurufen oder einen bestimmten Code-Block zu umgehen, gibt es im Kontextmenü die Funktion "Nächste Anweisung festlegen" ("Set Next Statement"). Alternativ kann man den kleinen gelben Pfeil links neben der aktuellen Anweisung auch mit der Maus auf eine andere Position ziehen. Führt man das Programm dann mit F5, F10 oder F11 weiter aus, wird das Programm an dieser Stelle fortgesetzt.


Fehlerbehebung
In Visual Studio gibt es eine sehr hilfreiche Funktion namens  Bearbeiten und Fortfahren / ( Edit and Continue), mit der man während des Debuggens den Code ändern und dann weiter ausführen kann. So kann man Fehler beheben und auch gleich ausprobieren, ob es tatsächlich so funktioniert. Natürlich muss man dafür sorgen, dass die geänderte Zeile erneut ausgeführt wird, z.B. so wie im vorangegangenen Abschnitt beschrieben. Bearbeiten und Fortfahren steht bis einschließlich VisualStudio 2012 allerdings nur für x86-Anwendungen zur Verfügung.


Systematische Fehlersuche
Um die Qualität einer Anwendung sicherzustellen und Fehler systematisch aufzuspüren, sollte man unbedingt jede Funktion mithilfe von  Unit-Tests überprüfen, siehe auch [url=http://www.mycsharp.de/wbb2/thread.php?threadid=110202][Artikel] Unit-Tests: Einführung in das Unit-Testing mit VisualStudio[/url].

Und noch ein Tipp: Auch bei hartnäckigen Fehlern sollte man nicht die Geduld verlieren sondern systematisch vorgehen. Eine Anleitung, wie man in solchen Fällen vorgehen kann, gibt es unter  [Tutorial] Vertrackte Fehler durch Vergleich von echtem Projekt mit minimalem Testprojekt finden.


Systematische Fehlervermeidung
Um die gewünschte Funktionalität eines Programms von vornherein und dauerhaft zu gewährleisten, gibt es nur eine Lösung, nämlich konsequentes  Test-Driven Development (TDD).


Fazit
Mithilfe von Funktionen wie Einzelschritt-Debugging, Haltepunkten und Variablen-Überwachung lassen sich Fehler in Programmen schnell und zielsicher aufspüren und beheben.

Weeks of programming can save you hours of planning

M
7 Beiträge seit 2012
vor 10 Jahren

Verständlich geschrieben. Und sicher hilfreich für jeden Ein- / Umsteiger. 👍
Nebensätzlich erwähnenswert wäre sicher noch das "Attach Process", da früher oder später jeder vor der Aufgabe steht z.B. einen Service zu debuggen.
Eine schöne Abrundung für die Erklärung von Breakpoints wäre noch das De- Aktivieren. Was m.E. sehr hilfreich ist für das Szenario in dem man zuerst mehrere BPs setzt um einen grösseren Ablauf anzuschauen und dann nach und nach vertieft weitere BPs hinzufügt.

64 Beiträge seit 2012
vor 10 Jahren

Für die jenigen die nur in der Expressversion von Visual Studio [2010 oder tiefer] arbeiten, gibt es die Möglichkeit der bedingten Haltepunkte (Conditional Breakpoints) nicht von Haus aus.

Allerdings kann man sich mit:


#if DEBUG
    if( i == 0 )  System.Diagnostics.Debugger.Break();
#endif

seinen eigenen Conditional Breakpoint bauen.

++Rekursion ++
(lat. , die) siehe Rekursion

709 Beiträge seit 2008
vor 10 Jahren

Für die jenigen die nur in der Expressversion von Visual Studio arbeiten, gibt es die Möglichkeit der bedingten Haltepunkte (Conditional Breakpoints) nicht von Haus aus.

Seit Visual Studio Express 2012 scheint das auch da möglich zu sein. 😃

64 Beiträge seit 2012
vor 10 Jahren

Huch das habe ich nicht geprüft, Danke! 😃 Hatte nur gemerkt das es in 2010 nicht klappt.
Ich habe meinen Beitrag entsprechend geändert.

++Rekursion ++
(lat. , die) siehe Rekursion

189 Beiträge seit 2014
vor 8 Jahren

Aufgrund der häufigen Verweise auf diesen Artikel möchte ich noch anmerken, dass das openbook: Visual C# vom Rheinwerk-Verlag dieses Thema auch behandelt.
Kapitel 7: Fehlerbehandlung und Debugging beinhaltet Kapitel 7.3: Fehlersuche mit Visual Studio [...].
Vielleicht hilft dem einen oder anderen die andere Art der Formulierung weiter.

VG Ezio

2.078 Beiträge seit 2012
vor 2 Jahren

@MrSparkle:

Ich bin mir nicht ganz sicher, ob das hier rein gehört, oder lieber ins Kritik-Forum, aber dein Artikel scheint etwas zerpflückt 🙂
Beim Zitieren bekomme ich auch nicht das, was ich aus dem Forum so kenne, sondern scheinbar den ganzen HTML-Code des Beitrags.

Sieht aus, als hast Du hier Funktionen genutzt, die das neue Forum (noch) nicht unterstützt?
Außerdem gibt's die Bilder nicht mehr.

Kannst Du das korrigieren?

MrSparkle Themenstarter:in
5.657 Beiträge seit 2006
vor 2 Jahren

Danke für den Hinweis! Da ist beim Migrieren etwas verloren gegangen. Wir werden uns darum kümmern.

Weeks of programming can save you hours of planning