EMZETT.
Login

Debugger gdb und lldb: Programme schrittweise untersuchen

Kurz: Ein Debugger hält ein laufendes Programm an, zeigt Variablen und Aufrufkette und führt es Zeile für Zeile aus; gdb und lldb sind die Standardwerkzeuge für C, C++ und Rust.

Genauer: Statt printf überall zu verteilen, kann man dem Programm beim Arbeiten zusehen. Der Debugger startet es unter Kontrolle, stoppt an Haltepunkten (Breakpoints) und erlaubt, Speicher und Register zu untersuchen. Auch nach einem Absturz (Segmentation Fault) hilft er mit einer Core-Datei.

Im Detail

Vorbereitung

Kompiliere mit Debug-Symbolen und ohne starke Optimierung:

gcc -g -O0 programm.c -o programm      # C
g++ -g -O0 programm.cpp -o programm    # C++
cargo build                            # Rust (Debug-Profil)

Ohne -g fehlen Zeilen- und Variablennamen. -O0 verhindert, dass der Compiler Code umstellt.

Wichtige gdb-Befehle

gdb ./programm
(gdb) break main            # Haltepunkt (auch: break datei.c:42)
(gdb) run                  # starten (run arg1 arg2)
(gdb) next    (n)          # nächste Zeile (ohne in Funktionen zu gehen)
(gdb) step    (s)          # in Funktion hineingehen
(gdb) continue (c)         # weiterlaufen bis zum nächsten Haltepunkt
(gdb) print variable       # Wert anzeigen (print *zeiger, print arr[0]@5)
(gdb) display variable     # nach jedem Schritt anzeigen
(gdb) backtrace (bt)       # Aufrufkette
(gdb) frame 2              # Stack-Frame wechseln
(gdb) watch variable       # stoppen, wenn sich der Wert ändert
(gdb) info locals          # lokale Variablen
(gdb) quit

lldb (Standard auf macOS/LLVM) kennt ähnliche Befehle (b main, r, n, s, p var, bt).

Abstürze analysieren

Bei einem Segmentation Fault gdb ./programm, run, nach dem Absturz bt und frame N, um die Stelle und die Variablenwerte zu sehen. Mit Core-Dateien (ulimit -c unlimited, gdb programm core) lassen sich Abstürze nachträglich untersuchen. Ergänzend finden Valgrind und AddressSanitizer (-fsanitize=address) Speicherfehler (Überläufe, use-after-free).

Komfort und andere Sprachen

Grafische Oberflächen: VS Code (C/C++-Erweiterung, CodeLLDB), CLion, gdb -tui und gdbgui. Für Python gibt es pdb/breakpoint(), für JavaScript die Browser-Entwicklerwerkzeuge/node --inspect, für Java Debugger der IDE. Das Prinzip ist überall gleich: Haltepunkt setzen, Zustand ansehen, schrittweise weitergehen, Hypothese prüfen.

Siehe auch: Debugging, Stacktrace lesen, Valgrind und Sanitizer, Segmentation Fault