Att avlusa program
När kommer löss i program, buggar, så är det mycket
praktiskt att kunna stega sig igenom ett program och studera vad
som faktiskt sker med variabler och funktioner. Det finns ett
antal att välja på och två exempel är DDD (gör 'module add ddd'
och starta med 'ddd &') och gdb. DDD är faktiskt bara ett grafiskt
skal för gdb, men är praktiskt då man vill kunna klicka sig om
kring i ett program. Styrkan i DDD ligger i att det är bekvämt att
analysera komplicerade datastrukturer eftersom man kan få dem
uppritade i ett fönster.
Om man vill dra nytta av den integrerade utvecklingsmiljön som
Emacs erbjuder finns det även ett emacs-skal till gdb.
Emacs förenklar mycket av användningen och
binder på ett trevligt sätt ihop avlusning med programeditering.
Det som beskrivs nedan är till mycket liten del
Emacs-specifikt. Kommandona kan även ges till DDD och du kan
även köra gdb direkt i ett terminalfönster, men du
kommer snart att upptäcka att det är jobbigt att skriva om
kommandon et.c.
GDB under Emacs
Starta med kommandot 'M-x gdb'. Emacs frågar då efter vilket
program (körbar fil, inte C-filen) som du vill debugga. (Tänk på
att du måste ha kompilerat programmet med väljaren '-g' för att
det här ska fungera.) Emacs kommer nu att att två buffrar, en för
programlistningen och en för kommandon. Alla kommandon i gdb har
långa namn, men unika prefix kan användas (d.v.s. om det finns
kommandona 'step' och 'search' har unika prefix 'st' respektive
'se') och det är till och med så att ofta använda kommandon kan
ges med en enda bokstav (t.ex. 'step' och 'print' ges av 's' och
'p').
Här är en lista med de vanligaste kommandona i gdb.
- help
- Om du ger ett argument (t.ex. 'help run') så beskrivs allt
om kommandot 'run'. Utan argument visas vad du har att välja
på.
- run
- Startar programmet och kör det till det bryts av
exekveringen når en brytpunkt, ett allvarligt programfel
uppstår eller du ger emacs-kommandot 'C-c C-c'.
- break
- Kommandot tar ett argument som antingen är ett radnummer i
den visade källkodsfilen eller ett funktionsnamn. I det första
fallet bryts körningen då vi nått givet radnummer och i det
andra fall bryts programmet då första kodraden i funktionen
ska exekveras.
- delete
- Varje brytpunkt har ett nummer. Ge nummret ett argument så
blir du av med en oönskad brytpunkt.
- print
- Skriver ut värdet på uttrycket du gett som
argument. Exempel: 'print i' ger dig värdet av i, 'print &i' ger
dig adressen av i, 'print *p' ger dig värdet av det som p
pekar på, och 'print i+17' ger dig precis 17 adderat till
v'rdet av i.
- display
- För att slippa skriva 'print' upprepade gånger och lätt
kunna följa vad som händer med en variabel under körningens
gång kan man begära att ett uttryck skrivs ut varje gång
programmet bryts. Exempel: 'display *p'.
- step
- Om programmet har brytits kontrollerat (utan programfel) kan
du begära att exakt en rad i programmet ska exekveras. Om det
är en funktion som du själv har skrivit (eller som finns i ett
bibliotek kompilerat med -g) så går vi ner i funktionen och
exekverar vidare där.
- next
- Nästan likadant som 'step', men den går ej ner i
funktionsanrop. Bra om man vill undvika detaljer.
- cont
- Låter programmet fortsätta köra tills nästa brytning.
- up, down
- Om du har följt en rad funktionsanrop och tappat
sammanhanget kan du med hjälp av dessa kommandon röra dig upp
och ner i anropskedjan.
- until
- I loopar med många varv kan det vara skönt att slippa ur
loopen utan att sätta en ny brytpunkt. Kommandot 'until' låter
dig köra vidare programmet tills du kommer till en rad du inte
har varit vid tidigare.
Emacs-stöd
Det är egentligen tre saker som gör det värt att köra gdb under Emacs.
- Du kan lätt hoppa mellan källkod och debugger, och det
markeras i källkoden med en liten pil i vänstra kanten var
körningen befinner sig.
- På tangenten 'M-p' kommer du åt tidigare kommandon givna i
bufferten. Om du börjat skriva på ett kommando ger samma
tangent de tidigare kommandona som börjar likadant. På samma
sätt går 'M-n' neråt i listan av tidigare kommandon. Det här
gäller alla program som körs i en emacs-buffer.
- Alla Emacs-tricks för att editera går fortfarande att använda.
Strategi
Hur du ska debugga beror på vilket fel du har/söker.
Ditt program kraschar
Om ditt program kraschar så är det enklaste att ge kommandot 'run'
och se vad som händer. När programmet bryts så visas i
källkodsfönstret var felet (eller dess resultat) uppstår och det
är lätt att gå vidare med att analysera värdet av olika variabler
och jämföra deras värden med vad de borde ha och hitta lämpliga
platser att sätta brytpunkter.
Om du söker ett fel
Ibland är utdata fel utan att programmet har krashat. Börja då med
att stega igenom en viktig funktion (t.ex. main) m.h.a. 'next' för
att finna vart du ska rikta din uppmärksamhet.
Lars Arvestad
Last modified: Mon Nov 23 11:04:02 MET 1998