GDB - Szybki przewodnik
Debugger to program, który uruchamia inne programy, umożliwiając użytkownikowi sprawowanie kontroli nad tymi programami i badanie zmiennych w przypadku wystąpienia problemów.
Debugger GNU, który jest również nazywany gdb, to najpopularniejszy debugger dla systemów UNIX do debugowania programów C i C ++.
GNU Debugger pomaga w uzyskaniu informacji na następujące tematy:
Jeśli zdarzył się zrzut pamięci, to na jakiej instrukcji lub wyrażeniu wystąpił błąd programu?
Jeśli podczas wykonywania funkcji wystąpi błąd, który wiersz programu zawiera wywołanie tej funkcji i jakie są parametry?
Jakie są wartości zmiennych programu w określonym momencie podczas wykonywania programu?
Jaki jest wynik określonego wyrażenia w programie?
Jak debuguje GDB?
GDB umożliwia uruchomienie programu do określonego punktu, a następnie zatrzymanie i wydrukowanie wartości pewnych zmiennych w tym punkcie lub przejście przez program po jednym wierszu na raz i wydrukowanie wartości każdej zmiennej po wykonaniu każdego wiersza.
GDB używa prostego interfejsu wiersza poleceń.
Zwraca uwagę
Mimo że GDB może pomóc w wykrywaniu błędów związanych z wyciekiem pamięci, nie jest narzędziem do wykrywania wycieków pamięci.
GDB nie może być używane dla programów, które kompilują się z błędami i nie pomaga w naprawianiu tych błędów.
Przed przystąpieniem do instalacji sprawdź, czy masz już zainstalowany gdb w systemie Unix, wydając następujące polecenie:
$gdb -help
Jeśli GDB jest zainstalowany, wyświetli wszystkie dostępne opcje w GDB. Jeśli GDB nie jest zainstalowany, przejdź do nowej instalacji.
Możesz zainstalować GDB w swoim systemie, wykonując proste kroki omówione poniżej.
step 1: Upewnij się, że masz wymagania wstępne do zainstalowania gdb:
Kompilator C zgodny z ANSI (zalecany jest gcc - pamiętaj, że gdb może debugować kody generowane przez inne kompilatory)
Wymagane jest 115 MB wolnego miejsca na partycji, na której chcesz zbudować gdb.
Wymagane jest 20 MB wolnego miejsca na partycji, na której zamierzasz zainstalować gdb.
Program dekompresyjny GNU, gzip
Plik make narzędzie - wiadomo, że wersja GNU działa bez problemu, inne prawdopodobnie też.
step 2: Pobierz dystrybucję źródłową gdb z ftp.gnu.org/gnu/gdb. (Użyliśmy gdb-6.6.tar.gz instrukcje.) Umieść pliki dystrybucyjne w katalogu kompilacji.
step 3:W katalogu kompilacji zdekompresuj gdb-6.6.tar.gz i wyodrębnij pliki źródłowe z archiwum. Po zakończeniu rozpakowywania plików zmień katalog roboczy na katalog gdb-6.6, który został automatycznie utworzony w katalogu kompilacji.
$ build> gzip -d gdb-6.6.tar.gz
$ build> tar xfv gdb-6.6.tar
$ build> cd gdb-6.6
step 4: Uruchom skrypt konfiguracyjny, aby skonfigurować drzewo źródłowe dla swojej platformy.
$ gdb-6.6> .⁄configure
step 5: Skompiluj gdb przy użyciu make użyteczność.
$ gdb-6.6> make
step 6: Zaloguj się jako root i zainstaluj gdb za pomocą następującego polecenia.
$ gdb-6.6> make install
step 7: W razie potrzeby miejsce na dysku można odzyskać, usuwając katalog budowania gdb i plik archiwum po zakończeniu instalacji.
$ gdb-6.6> cd ..
$ build> rm -r gdb-6.6
$ build> rm gdb-6.6.tar
Masz teraz zainstalowany gdb w swoim systemie i jest gotowy do użycia.
ZA Debugging Symbol Tableodwzorowuje instrukcje w skompilowanym programie binarnym na odpowiadające im zmienne, funkcje lub wiersze w kodzie źródłowym. To mapowanie może wyglądać następująco:
Instrukcja programu ⇒ nazwa pozycji, typ pozycji, oryginalny plik, zdefiniowany numer linii.
Tabele symboli mogą być osadzone w programie lub przechowywane jako osobny plik. Jeśli więc planujesz debugować swój program, konieczne jest utworzenie tabeli symboli, która będzie zawierała informacje wymagane do debugowania programu.
Możemy wnioskować o następujących faktach dotyczących tablic symboli:
Tablica symboli działa dla określonej wersji programu - jeśli program się zmieni, należy utworzyć nową tablicę.
Kompilacje debugowania są często większe i wolniejsze niż wersje detaliczne (bez debugowania); Kompilacje debugowania zawierają tablicę symboli i inne informacje pomocnicze.
Jeśli chcesz debugować program binarny, którego sam nie skompilowałeś, musisz uzyskać tablice symboli od autora.
Aby umożliwić GDB odczytanie wszystkich tych informacji wiersz po wierszu z tablicy symboli, musimy skompilować je nieco inaczej. Zwykle kompilujemy nasze programy jako:
gcc hello.cc -o hello
Zamiast robić to, musimy skompilować się z flagą -g, jak pokazano poniżej:
gcc -g hello.cc -o hello
GDB oferuje dużą listę poleceń, jednak najczęściej używane są następujące polecenia:
b main - Umieszcza punkt przerwania na początku programu
b - Wstawia punkt przerwania w bieżącej linii
b N - Wstawia punkt przerwania w linii N
b +N - Wstawia punkt przerwania N linii w dół od bieżącej linii
b fn - Wstawia punkt przerwania na początku funkcji „fn”
d N - usuwa punkt przerwania numer N
info break - lista punktów przerwania
r - Uruchamia program do punktu przerwania lub błędu
c - Kontynuuje działanie programu aż do następnego punktu przerwania lub błędu
f - Działa do zakończenia bieżącej funkcji
s - Uruchamia następną linię programu
s N - Uruchamia następne N wierszy programu
n - Podobnie jak s, ale nie wchodzi w funkcje
u N - Działa do momentu uzyskania N linii przed bieżącą linią
p var - Drukuje bieżącą wartość zmiennej „var”
bt - Drukuje ślad stosu
u - Podnosi poziom w stosie
d - Spada poziom w stosie
q - Kończy gdb
Pierwsze kroki: uruchamianie i zatrzymywanie
gcc -g myprogram.c
Kompiluje myprogram.c z opcją debugowania (-g). Nadal otrzymujesz plik a.out, ale zawiera on informacje o debugowaniu, które pozwalają na używanie zmiennych i nazw funkcji wewnątrz GDB zamiast surowych lokalizacji pamięci (nie jest to zabawne).
gdb a.out
Otwiera GDB z plikiem a.out, ale nie uruchamia programu. Zobaczysz znak zachęty (gdb) - wszystkie przykłady pochodzą z tego znaku zachęty.
r
r arg1 arg2
r <plik1
Trzy sposoby uruchomienia „a.out”, załadowane wcześniej. Możesz uruchomić go bezpośrednio (r), przekazać argumenty (r arg1 arg2) lub przesłać do pliku. Zazwyczaj przed uruchomieniem ustawiasz punkty przerwania.
help
h punktów przerwania
Wyświetla listę tematów pomocy (pomoc) lub uzyskuje pomoc na określony temat (punkty przerwania h). GDB jest dobrze udokumentowany.
q - Zamknij GDB
Przechodzenie przez kod
Stepping pozwala prześledzić ścieżkę programu i skupić się na kodzie, który ulega awarii lub zwraca nieprawidłowe dane wejściowe.
l
l 50
Moja funkcja
Wyświetla 10 wierszy kodu źródłowego dla bieżącego wiersza (l), określonego wiersza (l 50) lub funkcji (l moja funkcja).
Kolejny
Uruchamia program do następnej linii, a następnie zatrzymuje się. Jeśli bieżąca linia jest funkcją, wykonuje całą funkcję, a następnie zatrzymuje się.next jest dobry do szybkiego przechodzenia przez kod.
krok
Uruchamia następną instrukcję, a nie wiersz. Jeśli bieżąca instrukcja ustawia zmienną, jest taka sama jaknext. Jeśli jest to funkcja, wskoczy do niej, wykona pierwszą instrukcję, a następnie zatrzyma się.step jest dobry do zagłębiania się w szczegóły kodu.
koniec
Kończy wykonywanie bieżącej funkcji, a następnie wstrzymuje (nazywane również wyjściem). Przydatne, jeśli przypadkowo wszedłeś do funkcji.
Punkty przerwania lub punkty obserwacyjne
Punkty przerwania odgrywają ważną rolę w debugowaniu. Wstrzymują (przerywają) program, gdy osiąga określony punkt. Możesz sprawdzać i zmieniać zmienne oraz wznowić wykonywanie. Jest to pomocne, gdy wystąpi awaria wejścia lub wejścia mają być testowane.
przerwa 45
złamać moją funkcję
- Ustawia punkt przerwania w linii 45 lub w mojej funkcji. Program zatrzyma się, gdy osiągnie punkt przerwania.
zegarek x == 3
Ustawia punkt obserwacyjny, który wstrzymuje program, gdy zmienia się warunek (gdy zmienia się x == 3). Punkty obserwacyjne są świetne dla niektórych danych wejściowych (myPtr! = NULL) bez konieczności przerywania każdego wywołania funkcji.
kontyntynuj
Wznawia wykonywanie po wstrzymaniu przez punkt przerwania / obserwacyjny. Program będzie kontynuowany, dopóki nie osiągnie następnego punktu przerwania / obserwacyjnego.
usuń N
- Usuwa punkt przerwania N (punkty przerwania są numerowane podczas tworzenia).
Ustawianie zmiennych
Przeglądanie i zmienianie zmiennych w czasie wykonywania jest krytyczną częścią debugowania. Spróbuj podać nieprawidłowe dane wejściowe do funkcji lub uruchomić inne przypadki testowe, aby znaleźć główną przyczynę problemów. Zazwyczaj będziesz przeglądać / ustawiać zmienne, gdy program zostanie wstrzymany.
drukuj x
Wyświetla aktualną wartość zmiennej x. Możliwość używania oryginalnych nazw zmiennych jest powodem, dla którego potrzebna jest flaga (-g); programy kompilowane regularnie usuwają te informacje.
zestaw x = 3
ustaw x = y
- Ustawia x na ustawioną wartość (3) lub na inną zmienną (y)
zadzwoń do myfunction ()
zadzwoń do mojej innej funkcji (x)
zadzwoń do strlen (mystring)
Wywołuje funkcje zdefiniowane przez użytkownika lub funkcje systemowe. Jest to niezwykle przydatne, ale uważaj na wywoływanie błędnych funkcji.
wyświetlacz x
Stale wyświetla wartość zmiennej x, która jest pokazywana po każdym kroku lub pauzie. Przydatne, jeśli stale sprawdzasz określoną wartość.
undisplay x
- Usuwa stałe wyświetlanie zmiennej wyświetlanej przez polecenie wyświetlania.
Śledzenie wstecz i zmienianie ramek
Stos to lista bieżących wywołań funkcji - pokazuje, gdzie jesteś w programie. Rama przechowuje dane pojedynczego wywołania funkcji, takich jak argumenty.
bt
Backtraceslub wyświetla bieżący stos funkcji, aby pokazać, gdzie jesteś w bieżącym programie. Jeśli main wywołuje funkcję a (), która wywołuje b (), która wywołuje c (), śledzenie wstecz jest
c <= current location
b
a
main
up
na dół
Przejdź do następnej klatki w górę lub w dół na stosie funkcji. Jeśli jesteś wc, możesz się przenieść b lub a do badania zmiennych lokalnych.
powrót
- Zwraca z bieżącej funkcji.
Obsługa sygnałów
Sygnały to komunikaty generowane po pewnych zdarzeniach, takich jak licznik czasu lub błąd. GDB może wstrzymać się, gdy napotka sygnał; zamiast tego możesz je zignorować.
uchwyt [nazwa sygnału] [akcja]
uchwyt SIGUSR1 nostop
uchwyt SIGUSR1 noprint
uchwyt SIGUSR1 ignoruj
Poinstruuj GDB, aby ignorował określony sygnał (SIGUSR1), gdy wystąpi. Istnieją różne poziomy ignorowania.
Zapoznaj się z poniższymi przykładami, aby zrozumieć procedurę debugowania programu i zrzucania jądra.
Przykład debugowania 1
Ten przykład pokazuje, jak można uchwycić błąd, który występuje z powodu wyjątku zgłoszonego podczas dzielenia przez zero.
Przykład debugowania 2
Ten przykład ilustruje program, który może zrzucić rdzeń z powodu niezainicjowanej pamięci.
Oba programy są napisane w C ++ i generują zrzut pamięci z różnych powodów. Po przejrzeniu tych dwóch przykładów powinieneś być w stanie debugować programy w C lub C ++ generujące zrzuty jądra.
Po przejściu przez ten samouczek, musisz dobrze zrozumieć debugowanie programu C lub C ++ za pomocą GNU Debugger. Teraz nauczenie się funkcjonalności innych debuggerów powinno być bardzo łatwe, ponieważ są one bardzo podobne do GDB. Zdecydowanie zalecamy zapoznanie się z innymi debugerami, aby zapoznać się z ich funkcjami.
Na rynku dostępnych jest kilka dobrych debuggerów:
DBX Debugger- Ten debugger jest dostarczany wraz z Sun Solaris i możesz uzyskać pełne informacje o tym debugerze, korzystając ze strony podręcznika dbx, tj. Man dbx .
DDD Debugger- To jest graficzna wersja dbx, dostępna bezpłatnie w systemie Linux. Aby uzyskać szczegółowe informacje, użyj strony podręcznika man ddd, tj. Man ddd .
Szczegółowe informacje na temat Debuggera GNU można uzyskać pod następującym linkiem: Debugowanie za pomocą GDB