Programmierung

Debugging als systematische Fehlersuche im Code

netcomputing.de Redaktion5. Dezember 20225 Min. Lesezeit
Debugging als systematische Fehlersuche im Code
Photo by Nubelson Fernandes

Zusammenfassung

Debugging bezeichnet den systematischen Prozess, mit dem Entwickler die Ursache eines Softwarefehlers finden und beheben. Der Begriff geht auf einen dokumentierten Fall am Harvard-Rechner Mark II von 1947 zurück, tauchte aber schon in Thomas Edisons Laborbüchern der 1870er-Jahre auf. Vier gängige Methoden reichen von Breakpoints über Log-Ausgaben bis zur binären Fehlersuche mit git bisect. Werkzeuge wie GDB, pdb, die Chrome DevTools und die Debugger in Visual Studio Code oder IntelliJ IDEA setzen diese Methoden in der Praxis um.

Ein Programm tut selten beim ersten Versuch das, was sein Autor beabsichtigt hat. Der Prozess, mit dem Entwickler die Ursache eines fehlerhaften Verhaltens finden und beheben, heißt Debugging. Der Name geht auf einen dokumentierten Fall zurück: Am 9. September 1947 entfernte ein Team um den Ingenieur William B. Burke am Harvard-Rechner Mark II eine Motte aus einem Relais und klebte sie mit dem Vermerk "First actual case of bug being found" in das Logbuch. Das Buch liegt heute im National Museum of American History in Washington. Den Begriff selbst gab es schon länger: Thomas Edison verwendete "bug" bereits in den 1870er-Jahren in seinen Laborbüchern, unter anderem 1878 in einem Brief über kleinere technische Störungen an seinen Erfindungen. Zur Mark-II-Mannschaft gehörte auch die Programmiererin Grace Hopper. Sie fand die Motte nicht selbst, machte die Anekdote später aber bekannt.

Was beim Debugging passiert

Debugging beginnt, sobald ein Programm ein falsches Ergebnis liefert, abstürzt oder sich anders verhält als erwartet. Zuerst grenzt der Entwickler ein, unter welchen Bedingungen der Fehler auftritt. Danach verfolgt er Schritt für Schritt, an welcher Stelle im Code die Abweichung entsteht, oft indem er den Programmablauf anhält und den Inhalt einzelner Variablen prüft. Erst wenn die Ursache feststeht, folgt die Korrektur im Quellcode.

Warum unentdeckte Fehler teuer werden

Wie hoch die Kosten eines übersehenen Fehlers ausfallen können, zeigen zwei dokumentierte Fälle aus der Raumfahrt. Am 4. Juni 1996 zerstörte sich die Rakete Ariane 5 auf ihrem ersten Flug 37 Sekunden nach dem Start selbst. Ursache war eine Programmzeile aus der Vorgängerrakete Ariane 4, die einen 64-Bit-Messwert in eine 16-Bit-Zahl umwandelte, ohne den größeren Wertebereich der neuen Rakete zu berücksichtigen. Die Umwandlung überlief, die Steuersoftware stürzte ab, und die Rakete wich von ihrem Kurs ab. Drei Jahre später ging der Mars Climate Orbiter der NASA verloren, weil eine Bodensoftware ihre Werte in Pfund-Sekunden statt in Newton-Sekunden ausgab. Die Navigationssoftware der Sonde erwartete das metrische Einheitensystem und berechnete dadurch eine falsche Umlaufbahn. In beiden Fällen hätte ein systematischer Test der Grenzfälle den Fehler vor dem Start gefunden.

4 Methoden, mit denen Entwickler Fehler eingrenzen

  • Breakpoints setzen: Ein Breakpoint hält die Programmausführung an einer festgelegten Codezeile an. Der Entwickler sieht dort den aktuellen Wert jeder Variable und kann den Ablauf danach Zeile für Zeile fortsetzen.
  • Ausgaben protokollieren: Wo kein Debugger verfügbar ist oder ein Fehler erst unter Last auftritt, schreibt der Code Zwischenwerte in die Konsole oder eine Logdatei. Diese Methode ist älter als jeder grafische Debugger und funktioniert auch in verteilten Systemen mit mehreren Servern.
  • Den Code laut erklären: Die Technik heißt Rubber Duck Debugging, benannt nach einer Anekdote aus dem Buch "The Pragmatic Programmer" von Andrew Hunt und David Thomas aus dem Jahr 1999. Ein Programmierer erklärt seinen Code Zeile für Zeile einem Gegenüber, notfalls einer Gummiente auf dem Schreibtisch, und stößt dabei oft von selbst auf den Fehler.
  • Die Fehlerquelle eingrenzen: Tritt ein Fehler erst nach vielen Änderungen auf, hilft die binäre Suche im Versionsverlauf. Der Befehl git bisect markiert einen bekannt fehlerfreien und einen bekannt fehlerhaften Commit und lässt Git die Commits dazwischen der Reihe nach testen, bis der auslösende Commit feststeht.

Werkzeuge für die Fehlersuche im Code

Für kompilierte Sprachen wie C und C++ hat sich der GNU Debugger (GDB) durchgesetzt, unter macOS ergänzt durch LLDB aus dem LLVM-Projekt. Python bringt mit pdb einen textbasierten Debugger direkt in der Standardbibliothek mit. Im Browser übernimmt diese Aufgabe das Panel "Sources" in den Chrome DevTools: Es zeigt JavaScript-Breakpoints, Netzwerkaufrufe und den Aufrufstapel in einer einzigen Oberfläche. Entwicklungsumgebungen wie Visual Studio Code oder IntelliJ IDEA integrieren die passenden Sprach-Debugger direkt in den Editor, sodass ein Breakpoint per Mausklick neben der Zeilennummer entsteht.

Wer wiederkehrende Fehlerklassen von vornherein vermeiden will, ergänzt Debugging um zwei vorgelagerte Schritte. Automatisierte Tests melden einen einmal behobenen Fehler sofort, falls er zurückkehrt. Statische Analyse-Tools wie ESLint für JavaScript oder Pylint für Python zeigen bestimmte Fehlerarten schon an, bevor das Programm überhaupt läuft. Debugging ersetzt beides nicht: Es kommt erst dort zum Einsatz, wo Tests und Analyse ein Verhalten nicht vorhergesagt haben.

Häufig gestellte Fragen

Stammt der Begriff "Bug" tatsächlich von der Motte im Rechner Mark II?

Nur die bekannte Anekdote stammt von dort. Der Begriff selbst ist älter, Thomas Edison verwendete "bug" für technische Störungen bereits in den 1870er-Jahren, unter anderem 1878 in einem Brief. Der Vorfall von 1947 am Mark II, bei dem eine Motte aus einem Relais entfernt wurde, machte den Ausdruck durch den Logbucheintrag nur besonders bekannt.

Wie funktioniert Rubber Duck Debugging in der Praxis?

Ein Programmierer erklärt seinen Code Zeile für Zeile einem Gegenüber, notfalls einer Gummiente auf dem Schreibtisch. Allein durch das laute Erklären fällt häufig der Fehler auf, ohne dass die Ente selbst etwas beitragen muss. Die Technik geht auf eine Anekdote aus dem 1999 erschienenen Buch "The Pragmatic Programmer" von Andrew Hunt und David Thomas zurück.

Was genau macht der Befehl git bisect beim Eingrenzen eines Fehlers?

git bisect markiert einen bekannt fehlerfreien und einen bekannt fehlerhaften Commit und lässt Git die Commits dazwischen der Reihe nach automatisch testen. Nach wenigen Durchläufen der binären Suche steht der Commit fest, der den Fehler eingeführt hat. Die Methode eignet sich besonders, wenn ein Fehler erst nach vielen Änderungen sichtbar wird.

Ersetzen automatisierte Tests das manuelle Debugging?

Nein, sie ergänzen es nur. Automatisierte Tests melden einen einmal behobenen Fehler sofort, falls er zurückkehrt, und statische Analyse-Tools wie ESLint oder Pylint zeigen bestimmte Fehlerarten schon vor dem Programmstart an. Debugging kommt weiterhin dort zum Einsatz, wo Tests und Analyse ein Verhalten nicht vorhergesagt haben.

Quellen

  1. September 9: First Instance of Actual Computer Bug Being Found, Computer History Museum, abgerufen am 2026-08-26
  2. Ariane 501 – Presentation of Inquiry Board Report, European Space Agency (ESA), abgerufen am 2026-08-26
  3. Mars Climate Orbiter Team Finds Likely Cause of Loss, NASA / Jet Propulsion Laboratory, abgerufen am 2026-08-26
  4. git-bisect – Dokumentation, Git, abgerufen am 2026-08-26

Der Content wurde mit Hilfe von KI erstellt, vor allem in der Recherche und Vorformulierung. Prüfung und Abnahme durch unsere Redaktion.