Forskjell mellom versjoner av «Debugging»

Fra mn/ifi/INF1060
Hopp til: navigasjon, søk
Linje 15: Linje 15:
 
=== Programmet kræsjer: Prøv valgrind  ===
 
=== Programmet kræsjer: Prøv valgrind  ===
  
Hvis programmet kræsjer har du garantert gjort noe galt. Dette vises ofte i form av segmentation fault. Et triks er da å bruke programmet valgrind. Når du normalt kjører programmet slik: "./a.out print tresmaa.txt" kjører du det med valgrind slik: "valgrind ./a.out print tresmaa.txt".
+
Hvis programmet kræsjer har du garantert gjort noe galt. Dette vises ofte i form av ''segmentation fault''. Et triks er da å bruke programmet ''valgrind''. Når du normalt kjører programmet slik: <pre>$ ./a.out print tresmaa.txt</pre> kjører du det med valgrind slik: <pre>$ valgrind ./a.out print tresmaa.txt</pre>.  
 
 
For at valgrind skal skrive ut linjenummer i filen hvor det er problemer, må du huske å kompilere med opsjonen -g2 eller -g3.
 
 
 
Valgrind gir en del output som kan virke i overkant mye, men ofte gir kun én feil flere feilbeskjeder.  
 
  
 +
For at ''valgrind'' skal skrive ut linjenummer i filen hvor det er problemer, må du huske å kompilere med opsjonen '''-g2''' eller '''-g3'''.
 +
''Valgrind'' gir en del output som kan virke i overkant mye, men ofte gir kun én feil flere feilbeskjeder.
 
De vanligste feilmeldingene:  
 
De vanligste feilmeldingene:  
  
*Invalid read of size X - Du leser X byte fra minnet som ikke er allokert.  
+
* '''Invalid read of size X''' - Du leser X byte fra minnet som ikke er allokert.  
*Invalid write of size X - Du skriver til X byte i minnet som ikke er allokert. Dette skjer ofte hvis man allokerer til en streng slik: char *str = malloc(strlen(buf)), og glemmer at man må ha plass til null-byten på slutten, altså må man legge til 1.  
+
* '''Invalid write of size X''' - Du skriver til X byte i minnet som ikke er allokert. Dette skjer ofte hvis man allokerer til en streng slik: char *str = malloc(strlen(buf)), og glemmer at man må ha plass til null-byten på slutten, altså må man legge til 1.  
*Process terminating with default action of signal 11 (SIGSEGV) - Programmet ditt segger.  
+
* '''Process terminating with default action of signal 11 (SIGSEGV)''' - Programmet ditt segger fordi du roter med minnet, f.eks. ved å bruke en ulovlig minnepeker.  
*Use of uninitialised value of size 4 og Conditional jump or move depends on uninitialised value(s) er resultatet av at man bruker variabler/pekere som ikke er initalisert til en verdi.
+
* '''Use of uninitialised value of size 4 og Conditional jump or move depends on uninitialised value(s)''' er resultatet av at man bruker variabler/pekere som ikke er initialisert til en verdi.
  
 
=== Programmet kræsjer 2: Prøv GDB  ===
 
=== Programmet kræsjer 2: Prøv GDB  ===

Revisjonen fra 1. sep. 2010 kl. 22:27

Jeg skjønner ikke hva som skjer i programmet

En vanlig måte å debugge på er å skrive ut verdiene av variablene i programmet med printf. Ofte er nemlig problemet at du ikke har peiling på hva variablene faktisk inneholder, og da hjelper det ikke å gjette, noe veldig mange gjør. Skriv ut verdien så er det ingen tvil! Legg gjerne inn 20 printf-kall hvis det er nødvendig.

Utskriften kommer ikke alltid når jeg forventer det

Grunnen til dette er ofte på grunn av at printf skriver til stdout (standard out) som buffrer før dataene skrives ut. Dvs. at utskriften ikke nødvendigvis kommer med en gang, men heller når det passer eller når nok data blir sendt til bufferet. Dette er veldig ofte merkbart hvis utskriften ikke inkluderer newline (\n) på slutten.

For å unngå buffring, slik at man er sikker på at utskriften kommer med gang kan man skrive til stderr (standard error). Det kan gjøres med fprintf slik:

fprintf(stderr, "%s\n", "Dette sendes til stderr, og buffres ikke\n");

Les om mer standard streams

Programmet kræsjer: Prøv valgrind

Hvis programmet kræsjer har du garantert gjort noe galt. Dette vises ofte i form av segmentation fault. Et triks er da å bruke programmet valgrind. Når du normalt kjører programmet slik:
$ ./a.out print tresmaa.txt
kjører du det med valgrind slik:
$ valgrind ./a.out print tresmaa.txt
.

For at valgrind skal skrive ut linjenummer i filen hvor det er problemer, må du huske å kompilere med opsjonen -g2 eller -g3. Valgrind gir en del output som kan virke i overkant mye, men ofte gir kun én feil flere feilbeskjeder. De vanligste feilmeldingene:

  • Invalid read of size X - Du leser X byte fra minnet som ikke er allokert.
  • Invalid write of size X - Du skriver til X byte i minnet som ikke er allokert. Dette skjer ofte hvis man allokerer til en streng slik: char *str = malloc(strlen(buf)), og glemmer at man må ha plass til null-byten på slutten, altså må man legge til 1.
  • Process terminating with default action of signal 11 (SIGSEGV) - Programmet ditt segger fordi du roter med minnet, f.eks. ved å bruke en ulovlig minnepeker.
  • Use of uninitialised value of size 4 og Conditional jump or move depends on uninitialised value(s) er resultatet av at man bruker variabler/pekere som ikke er initialisert til en verdi.

Programmet kræsjer 2: Prøv GDB

GDB er en mer avansert debugger som gir langt flere muligheter enn valgrind. Hvis valgrind ikke er til hjelp kan det være nødvendig å ta i bruk GDB. GDB gir blant annet muligheter til å steppe gjennom programmet for hver instruksjon, samt skrive ut verdier av variabler midt i kjøringen.

Søk etter en guick guide for GDB