Forskjell mellom versjoner av «Debugging»

Fra mn/ifi/INF1060
Hopp til: navigasjon, søk
(Ny side: === 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…)
 
Linje 1: Linje 1:
=== Jeg skjønner ikke hva som skjer i programmet ===
+
=== 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.
+
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 ===
+
=== 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.
+
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:
+
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");
+
fprintf(stderr, "%s\n", "Dette sendes til stderr, og buffres ikke\n");
  
Les om mer standard streams
+
Les om mer standard streams  
  
=== 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: "./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.
+
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.
+
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.  
* 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 initalisert til en verdi.
  
=== Programmet kræsjer 2: Prøv GDB ===
+
=== 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.
+
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.  
  
 
[http://www.google.no/search?q=gdb+quick+guide Søk etter en guick guide for GDB]
 
[http://www.google.no/search?q=gdb+quick+guide Søk etter en guick guide for GDB]

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

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.
  • 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.

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