A.D.Danilecki, Poznan, Polska
Politechnika Poznanska, Wydzial Informatyki i Zarzadzania
W tej chwili adanilecki _malpa_ cs.put.poznan.pl
Z wykorzystaniem wielu listow z uwagami od wielu autorow
Krótki wstęp do programowania z wykorzystaniem inline assemblera x86


8. Używanie gdb


Ten rozdział powstał dzięki pomocy Pawła Krawczyka kravietz _mailto_ ceti.com.pl

Pierwszą metodą testowania jest jak używanie printfów, zmiennych globalne i wykomentowywanie kodu po to żeby dojść która instrukcja powoduje błąd. Jest to bardzo pracochłonne ale mało odkrywcze, do w końcu każdy kto pisze w C pod Linuxa stosuje/stosował podobną metodę. Po co zmienna globalne ? Z lenistwa. łatwo potem w wersji ostatecznej wykasować movl %%eax, %0 .. " : "m" (EAX) i mniej to zaciemnia program który i bez tego fatalnie się czyta.)
Możesz też spróbować debugować swój program za pomocą gdb. Aby skompilować program w ten sposób, by móc łatwo po nim się poruszać za pomocą gdb, wydaj polecenie :
gcc -g nazwa -o nazwa_prgramu_możliwego_do_debuggingu

Np : gcc -g moj.c -o moj. ("mój" jest normalnym prorgamem wykonywalnym, tyle że zawiera symbole pomagające w debuggingu) Następnie wydaj polecenie :
gdb moj .
Zaczniesz sesję z gdb. Teraz możesz ustawiać breakpointy :na linie, np
(gdb)b 9
na symbole
(gdb) b printf
lub na adresy
(gdb) b *0x008932ac
. Dodatkowo możesz kazać, by za każdym razem, gdy program się zatrzyma, wyświetlał aktualnie wykonywaną instrukcję :
(gdb) display/i $pc
Możesz też kazać mu zdeassemblować jakąś funkcję :
(gdb) disas main
lub obszar pamięci:
(gdb) disas 0x0234 0x23421
. Możesz teraz wyświetlać zmienne widoczne w danej funkcji/bloku programu, np
(gdb) p b (pod warunkiem że b jest widoczna w danym bloku programu, tj. albo globalna, albo zadeklarowana w tym bloku - po zakres widzialności odwołaj się do pierwszego lepszego podręcznika do C).

Możesz też wyświetlać informację o rejestrach
(gdb) p $eax
informację o tym, gdzie zaczynają się poszczególne linie
(gdb) info line 9
wypisać kod źródłowy wokół symbolu,
list main
wypisać adres symbolu, np (gdb) info line main

Teraz możesz juz uruchomić program : napisz
(gdb) run
Program zatrzyma na się na najbliższym breakpoincie. Możesz teraz posuwać się do następnych breakpointów za pomocą rozkazów step lub pojedyńczymi krokami si . W każdej chwili możesz uzyskać pomoc na tematy instrukcji w gdb : help, help breakpoints itd.
Nawet jeśli kompilowałeś program bez opcji -g, dalej możesz debugować program, tyle że musisz się po kodzie w assemblerze poruszać za pomocą instrukcji si breakpointy ustawiasz na adresy, nie możesz korzystać z informacji o liniach itd. Zauważ, że nawet jeśli skorzystasz z opcji -g, to i tak kod w assemblerze musisz oglądać za pomocą najlepiej instrukcji si . Zauważ że etykiety traktowane są jako symbole, tak samo jak funkcje; przypomnij sobie wreszcie z lekcji assemblera czy skądkolwiek że adres bieżącej instrukcji jest w %eip, czyli by wiedzieć gdzie jesteśmy można wydać instrukcję (gdb) p $eip
Poczytaj też info gdb : z linii poleceń wydaj polecenie info gdb, info gcc i miłej lektury.
Należy tez wspomniec o istniejacych nakladkach na gdb : xgdb, kgdb (dla środowiska KDE) oraz ddd (nie widziałem tej nakładki na oczy).