Powrót do strony głównej

GDB debugowanie C++: wyszukiwanie segfault w minuty

Przewodnik po GDB dla deweloperów C++ skupia się na wyszukiwaniu segfault, ustawianiu punktów przerwania, przeglądzie zmiennych i trybie TUI. Oparty na rzeczywistych przykładach awarii i nawigacji po kodzie bez rekompilacji.

GDB w C++: od segfault do szybkiego debugowania
Advertisement 728x90

GDB: krok po kroku debugowanie programów C++ bez strachu przed segfault

GDB pozwala precyzyjnie zlokalizować miejsce awarii programu w ciągu 15–30 sekund. Zamiast dodawać print do każdej funkcji i ponownie kompilować, użyj debuggera, aby w czasie rzeczywistym sprawdzić stos wywołań i wartości zmiennych. Aby móc korzystać z informacji debugowania, kompiluj z flagami -g -O0:

g++ -g -O0 -o myprogram myprogram.cpp

Sprawdź obecność danych debugowania poleceniem file myprogram. Uruchom: gdb ./myprogram, a następnie run. W przypadku segfault GDB zatrzyma się i wskaże dokładne miejsce za pomocą backtrace (bt).

Przykład awarii w std::string::operator= z null-tem wskaźnikiem this jest widoczny od razu w stosie:

Google AdInline article slot
#0 0x... in std::string::operator= (this=0x0, ...)
#1 0x... in UserData::setName (...)
#2 0x... in main ()

Włącz czytelny format wyświetlania: set print pretty on i set print demangle on.

Punkty przerwania i krokowe wykonanie

Ustaw punkty przerwania, by kontrolować przebieg programu:

  • break main — na początku funkcji main
  • break program.cpp:42 — na konkretnej linii
  • break UserData::setName — przy wejściu do metody
  • info break — lista wszystkich punktów przerwania

W C++ dla przeciążonych funkcji podaj pełną sygnaturę: break print(int) lub break print(std::string). Zaawansowany sposób: rbreak ^.*::print$ dla wszystkich metod print pasujących do wyrażenia regularnego.

Google AdInline article slot

Nawigacja po kodzie:

| Komenda | Skrót | Działanie |

|---------|-------|----------|

Google AdInline article slot

| next | n | przejdź do następnej linii bez wejścia do funkcji |

| step | s | przejdź do następnej linii z wejściem do funkcji |

| finish | fin | wykonaj funkcję do końca |

| continue | c | kontynuuj do następnego punktu przerwania |

W C++ unikaj step na wywołaniach STL, takich jak push_back — użyj next, aby nie zagłębiać się w implementację bibliotek.

Przeglądanie zmiennych i obiektów

Polecenia do inspekcji stanu:

  • print variable_name — wartość zmiennej
  • print *pointer — zawartość przez wskaźnik
  • print vec.size() — wywołanie metody
  • display variable_name — automatyczne wyświetlanie po każdym kroku
  • info locals — lokalne zmienne
  • info args — argumenty funkcji

GDB poprawnie renderuje typy C++:

print myVector
$1 = std::vector of length 5, capacity 8 = {1, 2, 3, 4, 5}

print myString
$2 = "Hello, World!"

Jeśli widzisz <optimized out> — ponownie skompiluj z -O0. Bez flagi -g nazwy zmiennych nie będą widoczne.

Tryb TUI do wizualnego debugowania

Włącz tryb TUI: tui enable — ekran podzieli się na dwie części: u góry kod z podświetlonym bieżącym wierszem, u dołu polecenia. Sterowanie:

  • layout src — kod źródłowy
  • layout asm — kod asemblerowy
  • layout split — kod + asembler
  • layout regs — rejestry
  • Ctrl + X, 2 — dwa okna
  • Ctrl + X, o — przełączanie między oknami
  • Ctrl + X, a — wyjście z trybu TUI

Tryb TUI ułatwia nawigację, pokazując kontekst bez konieczności liczenia linii.

Najczęstsze problemy i rozwiązania

| Problem | Rozwiązanie |

|--------|-------------|

| <optimized out> | Kompiluj z -O0 |

| Brak nazw zmiennych | Użyj flagi -g |

| Lokalne zmienne nie są widoczne | Wykonaj info locals wewnątrz funkcji |

| Wektor pokazuje śmieci | Użyj print vec._M_impl._M_start w starszych wersjach libstdc++ |

Podstawowe polecenia dla programistów średniozaawansowanych

Opanuj te 10 poleceń, które wystarczą do 90% przypadków:

  • r — uruchomienie programu
  • b — ustawienie punktu przerwania
  • bt — stos wywołań
  • n — next
  • s — step
  • fin — finish
  • c — continue
  • p — print
  • i locals — lokalne zmienne
  • q — wyjście z GDB

Co ważne

  • Stos wywołań (bt) rozwiązuje 70% problemów z segfault w kilka sekund, pokazując łańcuch wywołań aż do main.
  • Tryb TUI wizualizuje kod, redukując obciążenie poznawcze w dużych projektach.
  • Flagi -g -O0 są wymagane; bez nich debugowanie jest niemożliwe.
  • Różnica między next a step ma kluczowe znaczenie w C++ z STL — unikaj głębokiego przeszukiwania kodu bibliotek.
  • display oraz info locals/args zapewniają pełną kontrolę nad stanem bez potrzeby dodatkowych print.

— Editorial Team

Advertisement 728x90

Czytaj dalej