GDB: Schritt-für-Schritt C++-Debugging ohne Segfault-Furcht
GDB zeigt dir innerhalb von 15 bis 30 Sekunden genau auf, wo dein Programm abstürzt. Statt wild Print-Ausgaben zu verteilen und immer wieder neu zu kompilieren, nutze den Debugger, um den Aufrufstapel und die aktuellen Variablenwerte in Echtzeit zu prüfen. Kompiliere mit -g -O0, um Debug-Informationen einzubinden:
g++ -g -O0 -o myprogram myprogram.cpp
Überprüfe mit file myprogram, ob die Debug-Info vorhanden ist. Starte die Fehlersuche mit gdb ./myprogram, dann führe run aus. Bei einem Segfault hält GDB an und zeigt die genaue Position mittels backtrace (bt).
Ein Absturz in std::string::operator= mit einem null-Pointer für this erscheint sofort im Stacktrace:
#0 0x... in std::string::operator= (this=0x0, ...)
#1 0x... in UserData::setName (...)
#2 0x... in main ()
Aktiviere lesbare Ausgabe: set print pretty on und set print demangle on.
Breakpoints und Schrittweise Durchführung des Codes
Setze Breakpoints, um die Ausführung zu steuern:
break main— am Anfang von mainbreak program.cpp:42— an einer bestimmten Zeilebreak UserData::setName— beim Betreten einer Methodeinfo break— alle Breakpoints auflisten
Bei überladenen C++-Funktionen musst du die Signatur angeben: break print(int) oder break print(std::string). Fortgeschritten: rbreak ^.*::print$, um alle Methoden namens print per Regex zu finden.
Navigiere durch den Code:
| Befehl | Kurzbefehl | Aktion |
|--------|------------|--------|
| next | n | Zeile ausführen, ohne in Funktionen einzusteigen |
| step | s | Zeile ausführen und in Funktionen eintauchen |
| finish | fin | Bis zum Ende der Funktion laufen |
| continue | c | Weiterlaufen bis zum nächsten Breakpoint |
In C++ solltest du step nicht in STL-Aufrufe wie push_back verwenden — nutze stattdessen next, um im eigenen Code zu bleiben.
Untersuchung von Variablen und Objekten
Verwende diese Befehle, um Daten zu prüfen:
print variable_name— Wert der Variablen anzeigenprint *pointer— Zeiger dereferenzierenprint vec.size()— Methode aufrufendisplay variable_name— automatisch nach jedem Schritt anzeigeninfo locals— lokale Variablen anzeigeninfo args— Funktionsargumente anzeigen
GDB zeigt C++-Typen korrekt an:
print myVector
$1 = std::vector der Länge 5, Kapazität 8 = {1, 2, 3, 4, 5}
print myString
$2 = "Hello, World!"
Wenn du <optimized out> siehst, kompiliere erneut mit -O0. Ohne -g erscheinen keine Variablennamen.
TUI-Modus für visuelles Debugging
Aktiviere tui enable — der Bildschirm teilt sich: Oben wird der Quellcode mit der aktuellen Zeile hervorgehoben, unten erscheinen die Befehle. Verwende:
layout src— Quellcode-Ansichtlayout asm— Assembler-Ansichtlayout split— Quellcode + Assemblerlayout regs— Register-FensterCtrl + X, 2— zwei FensterCtrl + X, o— zwischen Fenstern wechselnCtrl + X, a— TUI-Modus verlassen
Der TUI-Modus vereinfacht die Navigation, da Kontext direkt sichtbar ist – ohne Zahlen zu zählen.
Häufige Probleme und Lösungen
| Problem | Lösung |
|--------|--------|
| <optimized out> | Mit -O0 neu kompilieren |
| Keine Variablennamen | -g-Flag verwenden |
| Lokale Variablen fehlen | Innerhalb der Funktion info locals ausführen |
| Vector zeigt Müll | Bei älterer libstdc++: print vec._M_impl._M_start verwenden |
Wichtige Befehle für mittelständische Entwickler
Beherrsche diese 10 Befehle für 90 % aller Debugging-Aufgaben:
r— starte Programmb— setze Breakpointbt— Rückverfolgung (Backtrace)n— nächster Schritts— Schritt in Funktionfin— bis zum Ende der Funktionc— weiterlaufenp— drucke Variablei locals— lokale Variablen anzeigenq— beende GDB
Wichtige Erkenntnisse
- Aufrufstapel (
bt) löst 70 % der Segfaults in Sekunden und zeigt den vollen Weg zurück zurmain. - TUI-Modus visualisiert den Code und reduziert die mentale Belastung bei komplexen Projekten.
-g -O0sind Pflicht; ohne sie ist Debugging wirkungslos.nextvsstepist entscheidend in C++ mit STL — vermeide tiefes Eintauchen in Bibliothekscode.displayundinfo locals/argsgeben volle Sicht auf den Zustand, ohne den Code mit Print-Befehlen zu belasten.
— Editorial Team
Noch keine Kommentare.