C++
VeröffentlichtRevision 1

Debugger, Warnungen und Sanitizer

Debugging ist die systematische Suche nach Programmfehlern. Ein Debugger kann ein laufendes Programm anhalten, einzelne Schritte ausführen und Werte anzeigen. Ein Breakpoint ist ein Haltepunkt an einer ausgewählten Codestelle.

Debugger, Warnungen und Sanitizer#

Dateien, Fehler und Werkzeuge · Lektion 51 von 60

Voraussetzungen: Compiler, Zeigerfallen. Lernziel: Du untersuchst den tatsächlichen Ablauf statt nur Vermutungen zu ändern.

Debugging ist die systematische Suche nach Programmfehlern. Ein Debugger kann ein laufendes Programm anhalten, einzelne Schritte ausführen und Werte anzeigen. Ein Breakpoint ist ein Haltepunkt an einer ausgewählten Codestelle.

Dieses Programm ist vollständig, enthält aber bewusst einen logischen Fehler: Es soll den Mittelwert berechnen und verliert dabei den Nachkommateil.

C++
1#include <iostream>2 3double mittelwert(int links, int rechts) {4    return (links + rechts) / 2;5}6 7int main() {8    std::cout << mittelwert(3, 4) << '\n';9}

Ein überprüfbarer Ablauf#

  1. Erzeuge einen Debug-Build mit Symbolinformationen, etwa bei GCC/Clang mit -g -O0.

  2. Setze einen Haltepunkt in mittelwert.

  3. Starte im Debugger und prüfe links und rechts.

  4. Untersuche den Ausdruck vor der Rückgabe.

  5. Ersetze die Rechnung für diesen Ansatz durch (static_cast<double>(links) + rechts) / 2.0 und prüfe erneut.

Debugsymbole verbinden Maschinencode mit Namen und Quelltextstellen. Step into steigt in einen Funktionsaufruf ein, Step over führt ihn als einen Schritt aus, Step out läuft bis zur Rückkehr. Der Call Stack zeigt die aktuelle Aufrufkette.

Kleine Reproduktionen#

Eine Reproduktion ist ein verlässlicher Weg, den Fehler erneut auszulösen. Notiere Eingabe, erwartetes Ergebnis, tatsächliches Ergebnis und Buildkonfiguration. Verringere ein großes Programm auf das kleinste Beispiel, das den Fehler noch zeigt. Das grenzt die Ursache besser ein als viele gleichzeitige Änderungen.

Sanitizer#

Ein Sanitizer ergänzt Prüfinstrumentierung in einem Build. AddressSanitizer kann unter anderem Zugriffe außerhalb gültiger Speicherbereiche und Use-after-free erkennen. Ein unterstützter Clang-Aufruf lautet beispielsweise:

Nur Text
1clang++ -std=c++17 -g -O1 -fsanitize=address -fno-omit-frame-pointer main.cpp -o programm

Die Clang-Dokumentation zu AddressSanitizer beschreibt Unterstützung und Diagnose. UndefinedBehaviorSanitizer prüft weitere ausgewählte Regelverletzungen; ThreadSanitizer untersucht bestimmte Nebenläufigkeitsfehler. Nicht jede Kombination ist auf jeder Plattform verfügbar oder miteinander kombinierbar.

Ein sauberer Sanitizerlauf beweist nur etwas über die ausgeführten Pfade. Er beweist nicht, dass alle möglichen Eingaben sicher sind. Warnungen, gezielte Tests und Verständnis der Lebensdauer ergänzen sich.

Übung#

Warum ist ein korrektes Ergebnis für mittelwert(2, 4) kein ausreichender Test?

Lösung

Die Summe ist gerade und die Ganzzahldivision verliert keinen sichtbaren Bruchteil. mittelwert(3, 4) deckt den Fehler auf. Unterschiedliche Grenz- und Normalfälle sind nötig.

Weiterlernen#

Zurück: Fehler mit throw, try und catch behandeln · Kursübersicht · Weiter: Tests, assert und Grenzfälle

Mitwirkende 1

Menschen, deren Änderungen in dieser Seite veröffentlicht wurden.

Kommentare 0

Kommentare sind für diese Seite deaktiviert.