(gdb) # the "run" command runs the program, and we need to remember to put a command line argument if we need one. Let's try it without an argument: (gdb) run Starting program: /afs/.ir.stanford.edu/users/c/g/cgregg/cs107/assignments/assign5/square This program will square an integer. Usage: ./square number [Inferior 1 (process 14146) exited normally] (gdb) (gdb) # the program caught that we tried to run without a number. (gdb) # let's run it again with 25 as the argument: (gdb) run 25 Starting program: /afs/.ir.stanford.edu/users/c/g/cgregg/cs107/assignments/assign5/square 25 This program will square an integer. 25 squared is 625 [Inferior 1 (process 14132) exited normally] (gdb) # we successfully ran the program. To look at the program, you can (gdb) # type 'list' or just 'l': (gdb) l 1 #include 2 #include 3 4 int square(int x); 5 6 int main(int argc, char *argv[]) { 7 printf("This program will square an integer.\n"); 8 9 // the program should have one number as an argument 10 if (argc != 2) { (gdb) # we type the return key to see the next lines, or just 'l' again: (gdb) l 11 printf("Usage:\n\t./square number\n"); 12 return 0; 13 } 14 15 // the first argument after the filename 16 int numToSquare = atoi(argv[1]); 17 18 int squaredNum = square(numToSquare); 19 20 printf("%d squared is %d\n",numToSquare,squaredNum); (gdb) 21 22 return 0; 23 } 24 25 26 int square(int x) { 27 int sq = x * x; 28 return sq; 29 } 30 (gdb) # when debugging, we often want to stop at a particular place (gdb) # in our code. We can set breakpoints at a line, or at a function. (gdb) break main Breakpoint 1 at 0x4005f3: file square.c, line 6. (gdb) break 20 Breakpoint 2 at 0x40064e: file square.c, line 20. (gdb) # now there are two breakpoints in the code. When we run the program (gdb) # again, it will stop on the first line: (gdb) run 25 Starting program: /afs/.ir.stanford.edu/users/c/g/cgregg/cs107/assignments/assign5/square 25 Breakpoint 1, main (argc=2, argv=0x7fffffffeab8) at square.c:6 6 int main(int argc, char *argv[]) { (gdb) # now we are stopped. A nice command is the "where" command to tell (gdb) # you exactly where you stopped: (gdb) where #0 main (argc=2, argv=0x7fffffffeab8) at square.c:6 (gdb) # if we type "l" again, we will get a list surrounding that line: (gdb) l 1 #include 2 #include 3 4 int square(int x); 5 6 int main(int argc, char *argv[]) { 7 printf("This program will square an integer.\n"); 8 9 // the program should have one number as an argument 10 if (argc != 2) { (gdb) # there are three commands that will continue the program. (gdb) # the first command is "next" (or just "n"), which is the (gdb) # "step over" command. It will run one line in your program, and (gdb) # it will step over functions -- i.e., it will run a function (gdb) # and not go into it. (gdb) n 7 printf("This program will square an integer.\n"); (gdb) n This program will square an integer. 10 if (argc != 2) { (gdb) # now we are on line 10. We can use a different command, "step" to (gdb) # go forward, as well, but "step" will go into a function if there (gdb) # is a function to go into: (gdb) s 11 printf("Usage:\n\t./square number\n"); (gdb) s printf (__fmt=) at /usr/include/x86_64-linux-gnu/bits/stdio2.h:104 104 return __printf_chk (__USE_FORTIFY_LEVEL - 1, __fmt, __va_arg_pack ()); (gdb) # oops! We stepped into the "printf" function! We can get back to our (gdb) # program by typing the "finish" command: (gdb) finish Run till exit from #0 printf (__fmt=) at /usr/include/x86_64-linux-gnu/bits/stdio2.h:104 Usage: ./square number 12 return 0; (gdb) # The final way to continue is to type "continue", which runs the (gdb) # program to completion, or to the next breakpoint. (gdb) continue Continuing. Breakpoint 2, main (argc=, argv=0x7fffffffeab8) at square.c:23 23 } (gdb) continue Continuing. [Inferior 1 (process 14154) exited normally] (gdb) # let's run it again with the proper argument (gdb) run 25 Starting program: /afs/.ir.stanford.edu/users/c/g/cgregg/cs107/assignments/assign5/square 25 Breakpoint 1, main (argc=2, argv=0x7fffffffeab8) at square.c:6 6 int main(int argc, char *argv[]) { (gdb) n 7 printf("This program will square an integer.\n"); (gdb) n This program will square an integer. 10 if (argc != 2) { (gdb) n 16 int numToSquare = atoi(argv[1]); (gdb) n 18 int squaredNum = square(numToSquare); (gdb) # now if we want to step into the square() function, we can, with s (gdb) s square (x=25) at square.c:27 27 int sq = x * x; (gdb) where #0 square (x=25) at square.c:27 #1 0x0000000000400636 in main (argc=, argv=0x7fffffffeab8) at square.c:18 (gdb) # the where command gives us a stack trace, and we can see that (gdb) # we are inside the square function, on line 27. (gdb) # We can take a look at variables here, too, with the 'p' command: (gdb) p x $1 = 25 (gdb) # "p x" says "print x" (gdb) # let's list the area around where we stopped (gdb) l 22 return 0; 23 } 24 25 26 int square(int x) { 27 int sq = x * x; 28 return sq; 29 } 30 31 (gdb) where #0 square (x=25) at square.c:27 #1 0x0000000000400636 in main (argc=, argv=0x7fffffffeab8) at square.c:18 (gdb) # we can go one step forward using next or step (gdb) n 29 } (gdb) p sq $2 = 625 (gdb) # we can look at the value of sq (gdb) finish Run till exit from #0 square (x=25) at square.c:29 main (argc=, argv=0x7fffffffeab8) at square.c:20 20 printf("%d squared is %d\n",numToSquare,squaredNum); Value returned is $3 = 625 (gdb) l 15 // the first argument after the filename 16 int numToSquare = atoi(argv[1]); 17 18 int squaredNum = square(numToSquare); 19 20 printf("%d squared is %d\n",numToSquare,squaredNum); 21 22 return 0; 23 } 24 (gdb) n 25 squared is 625 Breakpoint 2, main (argc=, argv=0x7fffffffeab8) at square.c:23 23 } (gdb) # we just called printf to print the result (gdb) cont Continuing. [Inferior 1 (process 15818) exited normally] (gdb)