gdb
Debuggowanie potrafi niemal wykładniczo skrócić czas szukania błędów w programie, więc warto nauczyć się sprawnie obsługiwać debugger. Dotychczas GNU Debugger był dla mnie czarną magią, a wzorem — ten z Visual Studio. Tylko gdzieś słyszałem/czytałem, że gdb ma takie same możliwości, ale nie dane mi było się o tym przekonać. Niedawno musiałem się nauczyć jego obsługi, dlatego napiszę sobie ściągawkę (nie, żeby z niej korzystać, ale żeby utrwalić).
Zanim zaczniesz
Musisz najpierw skompilować program z informacjami dla gdb. Robi opcja -g dla gcc.
Komendy
Zamiast miłego interfejsu graficznego, jest miły wiersz poleceń (co dla programisty jest wygodniejsze, bo nie musi odrywać rąk od klawiatury :>), w którym wpisujesz polecenia. Nie musisz podawać jej pełnej nazwy, wystarczy jednoznaczny początek (najczęstsze polecenia mają jedno/dwuliterowe synonimy). Działa dopełnienie tabulatorem! W razie czego: help komenda.
Start
Pierwszy paremtr to nazwa pliku wynikowego programu. Drugim może być numer procesu tego programu, jeśli chcesz zacząć debuggować już działający program.
Przydatne komendy:
- run [argumenty] - uruchamia program z podanymi (opcjonalnymi) argumentami
- continue - jeśli program jest zatrzymany, wznawia jego działanie
- finish - program się wykonuje aż do napotkania “return”; innymi słowy program działa aż do końca aktualnej ramki stosu
Stop
Żeby się gdzieś zatrzymać, trzeba ustawić breakpointy:
- breakpoint funkcja - ustala breakpoint na początek funkcji
- breakpoint [plik:]linia - ustala breakpoint na określoną linię pliku
- info breakpoints - wypisuje utawione breakpointy
- delete n - usuwa n-ty breakpoint
- condition n cond - ustala warunek dla n-tego breakpointa (program zatrzyma się na nim, jeśli zostanie spełniony warunek cond)
- ^C - czyli przerwanie z klawiatury, również zatrzymuje działający program i oddaje kontrolę gdb
Co się dzieje?
Kilka przydatnych komend, aby zorientować się, co się aktualnie dzieje:
- list - listing kodu (10 linii obecnego kontekstu, podana nazwa funkcji, numer linii, etc.)
- frame - aktualna ramka stosu oraz aktualna instrukcja
- backtrace - ślad stosu
- print x - wypisanie wartości x (to może być dowolne wyrażenie, razem ze zmiennymi w programie)
Tropimy
To, co najważniejsze, czyli śledzimy program krok po kroku:
- next - następna instrukcja (lub n instrukcji), bez wchodzenia wgłąb procedur
- step - j/w, ale z wchodzeniem wgłąb
Psujemy
Można przetestować kilka rzeczy w trakcie trwania programu:
- set x wartość - ustawiamy zmiennej x wartość
- call f(x) - wywołujemy funkcję f z argumentami (w tym wypadku tylko x)
Format zapisu zmiennych, funkcji i adresów.
Czasem chcemy się odwołać do zmiennej z jakiegoś innego zakresu albo funkcji składowej, wtedy piszemy zakres::x, jeśli np. zakres jest klasą, a x jej metodą/polem, albo zakres jest funkcją, a x jej zmienną lokalną. Odwołanie do konkretnej linii ma składnię plik:linia, np. test.c:244. Adres zapisujemy z gwiazdką na początku, np. *0×000000.
A na koniec: quit. I tyle. To było zaledwie 1/5 możliwości gdb, mimo to spokojnie wystarczy do efektywnego debuggowania. Chociaż dziesiątki printfów mają swój urok. ;)
Recent Comments