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.
  1. 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.
  2. 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.
  3. 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