gcc -ansi -g program.c -o programThe -g flag tells the compiler to add information for the debugger. To debug your program, simply say:
gdb programIf you omit program, gdb looks for an a.out file.
The rest of this handout contains several sample programs and how to use gdb to find the bugs. I recommend you use gdb to get used to it; in particular, make extensive use of its help command! Just type
helpto its prompt, and it will tell you what to do. Some of the features that I did not show which you will find particularly useful are the backtrace facility, which shows you what routines have been called and the values of the parameters.
#include <stdio.h> main() { int i, j = 0; for(i = 0; i < 100; i++); j += 2; printf("The value of j is: %d\n", j); }I compile and run it, and it does not work:
% gcc -ansi -g -o sample1 sample1.c % sample1 The value of j is: 2Oops! Let's get out gdb and see what happens. As usual, what I type is in boldface, what the computer prints is in plain face, and my comments are in italics.
% gdb sample1 GDB is free software and you are welcome to distribute copies of it under certain conditions; type "show copying" to see the conditions. There is absolutely no warranty for GDB; type "show warranty" for details. GDB 4.10.pl1 (sparc-sun-sunos4.1), Copyright 1993 Free Software Foundation, Inc... (gdb) l list 10 lines 1 #include <stdio.h> 2 3 main() 4 { 5 int i, j = 0; 6 for(i = 0; i < 100; i++); 7 j += 2; 8 printf("The value of j is: %d\n", j); 9 } (gdb) b main put in a breakpoint the program will stop at main when it is executed Breakpoint 1 at 0x22b4: file sample1.c, line 4. (gdb) r run the program Starting program: /usr/home/bishop/sample1 Breakpoint 1, main () at sample1.c:5 5 int i, j = 0; (gdb) n do the next statement 6 for(i = 0; i < 100; i++); (gdb) p i print i's value $1 = 100 (gdb) p j print j's value $2 = 0 aha! why is it not 200? It's not getting incremented right, so let's check the for loop ... and sure enough, that's where the problem is! (gdb) q The program is running. Quit anyway (and kill it)? (y or n) y
#include <stdio.h> main() { int i = 1, s; s = 3; while(i = 1){ s += s; if (s > 100) i = 0; } }
I compile and run it, and it hangs; I need to kill it with control-C:
% gcc -ansi -g -o sample2 sample2.c % sample2 ^C
Again, let's use gdb to figure out what happened:
% gdb sample2 GDB is free software and you are welcome to distribute copies of it under certain conditions; type "show copying" to see the conditions. There is absolutely no warranty for GDB; type "show warranty" for details. GDB 4.10.pl1 (sparc-sun-sunos4.1), Copyright 1993 Free Software Foundation, Inc... (gdb) l 1 #include <stdio.h> 2 3 main() 4 { 5 int i = 1, s; 6 7 s = 3; 8 while(i = 1){ 9 s += s; 10 if (s > 100) (gdb) b 9 Breakpoint 1 at 0x22b4: file sample2.c, line 9. (gdb) r Starting program: /usr/export/home/bishop/ECS-40/gdb/sample2 Breakpoint 1, main () at sample2.c:9 9 s += s; (gdb) p s $1 = 3 (gdb) n 10 if (s > 100) (gdb) c continue the run Continuing. Breakpoint 1, main () at sample2.c:9 9 s += s; (gdb) p s $2 = 6 seems to be doubling s okay (gdb) c Continuing. Breakpoint 1, main () at sample2.c:9 9 s += s; (gdb) p s $3 = 12 I'm tired of always typing "p s" when the program stops, so associate commands with that breakpoint (gdb) commands 1 Type commands for when breakpoint 1 is hit, one per line. End with a line saying just "end". p s end (gdb) c Continuing. Breakpoint 1, main () at sample2.c:9 9 s += s; $4 = 24 (gdb) c Continuing. Breakpoint 1, main () at sample2.c:9 9 s += s; $5 = 48 (gdb) c Continuing. Breakpoint 1, main () at sample2.c:9 9 s += s; $6 = 96 (gdb) p i $7 = 1 (gdb) c Continuing. Breakpoint 1, main () at sample2.c:9 9 s += s; $8 = 192 wait ... s is high here. Let's watch the value of i (gdb) watch i break whenever i changes Watchpoint 2: i (gdb) c Continuing. Watchpoint 2, i i just changed value Old value = 1 New value = 0 main () at sample2.c:12 12 } (gdb) c Continuing. Breakpoint 1, main () at sample2.c:9 9 s += s; $9 = 384 (gdb) c Continuing. Watchpoint 2, i why does i change -- the "if" is not executed! Look in the while expression; we used =, not == Old value = 1 New value = 0 main () at sample2.c:12 12 } (gdb) q The program is running. Quit anyway (and kill it)? (y or n) y
#include <stdio.h> main() /* counts digits, white space, others */ { int c, i, num_digits[10], num_white, num_other; num_white = num_other = 0; for(i = 0; i < 10; i++) /* initialize */ num_digits[i] = 0; while(c = getchar() != EOF){ switch(c){ case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': num_digits[c - '0']++; break; case ' ': case '\t': case '\n': num_white++; break; default: num_other++; break; } } printf("digits ="); for(i = 0; i < 10; i++) printf(" %d", num_digits[i]); printf("white space = %d, other = %d\n", num_white, num_other); }
Here's a data file for our testing and debugging pleasure:
7 4 88 6 6 3 4 7 87 8 2 34 5 7 3 21 123q52
I compile and run it, and it hangs:
% gcc -ansi -g -o sample3 sample3.c % sample3 < sample3.data ^C %
% gdb sample3 GDB is free software and you are welcome to distribute copies of it under certain conditions; type "show copying" to see the conditions. There is absolutely no warranty for GDB; type "show warranty" for details. GDB 4.10.pl1 (sparc-sun-sunos4.1), Copyright 1993 Free Software Foundation, Inc... (gdb) l 1 #include <stdio.h> 2 3 main() /* counts digits, white space, others */ 4 { 5 int c, i, num_digits[10], num_white, num_other; 6 num_white = num_other = 0; 7 for(i = 0; i <= 10; i++) /* initialize */ 8 num_digits[i] = 0; 9 while(c = getchar() != EOF){ 10 switch(c){ (gdb) b 8 Breakpoint 1 at 0x22f0: file sample3.c, line 8. (gdb) comm 1 Type commands for when breakpoint 1 is hit, one per line. End with a line saying just "end". p i end (gdb) r Starting program: /usr/export/home/bishop/ECS-40/gdb/sample3 Breakpoint 1, main () at sample3.c:8 8 num_digits[i] = 0; $1 = 0 (gdb) s s means to skip to the next statement; if it calls a function, you'll stop in that function. n means to skip to the next statement in this function; you skip over any functions that are called. 7 for(i = 0; i <= 10; i++) /* initialize */ (gdb) n Breakpoint 1, main () at sample3.c:8 8 num_digits[i] = 0; $2 = 1 (gdb) cond 1 i>=9 this means to skip breakpoint 1 until i >= 9 is true. (gdb) c Continuing. Breakpoint 1, main () at sample3.c:8 8 num_digits[i] = 0; $3 = 9 (gdb) c Continuing. Breakpoint 1, main () at sample3.c:8 8 num_digits[i] = 0; $4 = 10 now we should leave the loop (gdb) c Continuing. Breakpoint 1, main () at sample3.c:8 8 num_digits[i] = 0; $5 = 9 huh? This probably means we're overwriting i -- or our array has one less element than we think. (gdb) q The program is running. Quit anyway (and kill it)? (y or n) y
We make the change, and run it:
% sample3a < sample3.data digits = 0 0 0 0 0 0 0 0 0 0white space = 0, other = 48 % gdb sample3 GDB is free software and you are welcome to distribute copies of it under certain conditions; type "show copying" to see the conditions. There is absolutely no warranty for GDB; type "show warranty" for details. GDB 4.10.pl1 (sparc-sun-sunos4.1), Copyright 1993 Free Software Foundation, Inc... (gdb) l 1 #include <stdio.h> 2 3 main() /* counts digits, white space, others */ 4 { 5 int c, i, num_digits[10], num_white, num_other; 6 num_white = num_other = 0; 7 for(i = 0; i < 10; i++) /* initialize */ 8 num_digits[i] = 0; 9 while(c = getchar() != EOF){ 10 switch(c){ (gdb) b 10 since the for loop seems to work, it's probably in the while Breakpoint 1 at 0x23ac: file sample3.c, line 10. (gdb) r < sample3.data note I can redirect standard input, output, and error as if I were in the shell Starting program: /usr/export/home/bishop/ECS-40/gdb/sample3 < sample3.data Breakpoint 1, main () at sample3.c:10 10 switch(c){ (gdb) p c $1 = 1 oops ... there's no ^A in the file! (gdb) c Continuing. Breakpoint 1, main () at sample3.c:10 10 switch(c){ (gdb) p c $2 = 1 again! looks like an assignment when I should be comparing ... (gdb) quit The program is running. Quit anyway (and kill it)? (y or n) y
Department of Computer Science
University of California at Davis
Davis, CA 95616-8562