Spring 2009 |
Lab 2: GNU C Debugger |
Taken from:CS61C (Garcia & Patterson) |
You can start the debugger by a) running M-x gdb in emacs, and
typing gdb <filename>, or b) running gdb <filename>
in the shell. To debug intelligently, compile with the -g flag,
e.g. gcc -g -Wall -o baseconvert baseconvert.c.
How do you pass arguments to a program when using gdb?
How do you break at a certain point in a program? Describe two different ways (both ways may use the same base gdb command with different arguments).
How do you execute the next line of C code in the program after breaking at some point?
If the next line is a function call, you'll fly right through the call. How do you execute the C code, line by line, inside the function call?
How do you continue running the program after breaking?
How can you see the value of a variable (or even an expression) in gdb? Also (optional), how can you see this value in hex?
Instead of breaking, for example, at a particular function call, maybe you'd like to break only when the function is called with a particular set of arguments. In other words, you only want to break when a particular condition becomes true. How can you set this kind of conditional breakpoint?
How can you look at the function calls that have been made to get to the current point in the program, i.e. the program stack?
How do you exit out of gdb?
(optional) You break inside a function, but you want to see the value of a variable declared in the function that called the function that called your function. How do you do this (you may do this in several steps)?
2. Compile the file using the following command
gcc -g -Wall -o inf_loop inf_loop.c
This will compile the inf_loop.c file into an executable called inf_loop with the debugging flag turned on. Take a look at the inf_loop.c file. It has an infinite loop followed by a printf statement. Find a set of gdb commands that will allow you to execute the printf statement after the loop.
Once you have this working right, save your session to a file named
lab2-2.txt
If you are running
gdb from emacs, you can do this by saving your buffer in emacs as a file
(C-x C-w). If you are running gdb from the shell, you can run the script
<filename> command before running the gdb session in your
shell and then typing exit after you have exited the gdb session.
This will create a file with name filename which contains everything
you did in the gdb session.
3. Compile the recursive_print.c file using the following command
gcc -g -Wall -o recursive recursive_print.c
This will compile the recursive_print.c file into a executable called recursive. Take a look at the recursive_print.c file. It is supposed to print arguments passed on the command line in reverse order starting with the last argument and printing the executable recursive at the end. For example:
recursive yada yoda yodel
should print:
yodel
yoda
yada
recursive
However, currently if you run the file, it will cause a segmentation fault. :) Run the program under gdb while passing 6 English words as arguments to the program. Use gdb to answer the following questions. Which recursive call of PrintArg caused the segmentation fault? Give a set of gdb commands that will allow you to look at the value of the variable randomNum that was passed into the 3rd call of PrintArg (Counting the call from main as first). Give a fix for what is causing the segmentation fault (you are allowed to modify the code to test your fix). Hint: look at the value of ct at the time of each call to PrintArg.
Hopefully this helps you to understand how you can debug your own programs when they cause a segmentation fault.