CSC161 2010F Imperative Problem Solving

Laboratory: Debugging with DDD

Summary: We explore the use of DDD, one of the standard debugging systems.

Prerequisites: Understanding of basic C control structures. Understanding of Linux.

Preparation

a. Create a new directory for this lab. I would suggest CSC161/Labs/Debugging, but it's up to you.

b. Into that directory, copy the files /home/rebelsky/share/c/buggy/debugme.c and /home/rebelsky/share/c/buggy/segfault.c.

c. Copy the sample program from the sample session of the DDD tutorial, available at http://www.gnu.org/software/ddd/manual/html_mono/ddd.html#Sample Program.

d. Create your standard Makefile. Add -g to the C flags.

e. Add the following lines to your Makefile. These tell make to recompile sample if the Makefile changes.

sample: sample.c Makefile
        $(CC) $(CFLAGS) -o sample sample.c

Exercises

Exercise 1: GNU's DDD Tutorial

In this exercise, you will follow the steps in the DDD Sample Session, available at http://www.gnu.org/software/ddd/manual/html_mono/ddd.html#Sample Session. Unfortunately, the sample code contains some C syntax that we have not studied yet, so you may not understand everything in the sample program. However, you will still learn a lot about the use of the debugger, and that is the point of this laboratory lesson.

a. Follow the instructions in the sample tutorial, except for the exceptions listed below. Stop at the end of the tutorial (i.e., when you run into the sample source code again), which is way before the end of the web page.

b. Return to the top of GNU's tutorial, and scan through it again, this time making a crib sheet of the various DDD features you learned. I suggest recording how the various features are invoked and also brief descriptions of what they do. You may want to keep this crib sheet handy for future use! Note that we will reflect as a group on what you put on your crib sheet.

Exercise 2: Various Shorts

a. Compile the program sample.c again, this time without using the option -gstabs=, and try to run it in DDD. (The purpose of this exercise is so that you may recognize the error it produces should you happen to see it again in the future.) Recall that you'll need to update the Makefile, update sample.c (using touch sample.c) before you use make to recompile.

b. Recompile sample.c with the debugging information included. (Again: Update the Makefile, touch sample.c, run make.) Run ddd again. Move the mouse over various icons on the toolbar, and press the F1 key over some of them to read about what they do.

c. Try selecting What Now? from the Help menu (in the far upper-right corner of the DDD window). You may also want to try the Tip of the Day from the same menu.

Exercise 3: A Debugging Exercise

a. Use what you have learned to track down and fix the bugs in debugme.c with the help of DDD.

You may find the Interrupt button on the DDD Command Tool useful for this exercise. It will suspend your program -- a useful feature for locating infinite loops.

At some point during this exercise, try moving a breakpoint from one line to another by dragging the "stop sign" icon.

Exercise 4: Another Debugging Exercise

a. Read through segfault.c so that you understand what it does. If you see any bugs, please leave them in place for now.

b. Next, compile the program, and just for this once ignore the warning that it gives. When you run the program, it will probably throw a segmentation fault.

c. DDD can be very helpful in locating segmentation faults! To see this, open the program in DDD, and then press Run to run the program without any breakpoints.

Notice that the prompt for input values is shown in DDD's lower pane. You should go ahead and enter the numbers the program is asking for there. However, I expect that you will get a segmentation fault during that process.

Notice the segmentation fault error message, which also appears in DDD's lower pane. At this point, your program is no longer running. However, DDD can still help you find the problem.

Select Status->Backtrace from the DDD menu. A dialog window, titled "DDD: Backtrace", should open. You can widen the window by dragging its right edge.

You will see a list of three functions displayed in that window. This "backtrace" gives the current "function call stack" (ie, the sequence of function calls that are currently active). In this example, it tells you that main() is running, and within main(), a call to scanf() has been made. Further, within scanf() a call to _IO_vfscanf() has been made. This is where the program crashed... but the bug happened earlier.

Look again at the top line of the backtrace:

    #2 0x08048444 in main () at segfault.c:12

This tells you the segmentation fault happened at line 12 in main(). With this information, you should be able to find and fix this bug.

For Those with Extra Time

Extra 1: Shell Sort

If you are interested in learning more about the Shell Sort algorithm

used in GNU's DDD tutorial, you can read about it on Wikipedia.

 

History

February 2007 [Marge Coahran]

  • Created.

Monday, 11 October 2010 [Samuel A. Rebelsky]

  • Reformatted. Rewrote some text.

 

Disclaimer: I usually create these pages on the fly, which means that I rarely proofread them and they may contain bad grammar and incorrect details. It also means that I tend to update them regularly (see the history for more details). Feel free to contact me with any suggestions for changes.

This document was generated by Siteweaver on Wed Oct 13 11:33:10 2010.
The source to the document was last modified on Wed Oct 13 11:33:09 2010.
This document may be found at http://www.cs.grinnell.edu/~rebelsky/Courses/CSC161/2010F/Labs/debugging-lab.html.
A PDF version of this document may be found at http://www.cs.grinnell.edu/~rebelsky/Courses/CSC161/2010F/Labs/debugging-lab

Samuel A. Rebelsky, rebelsky@grinnell.edu

Copyright © 2010 Marge Coahran and Samuel A. Rebelsky. Please contact us for permission to reuse materials.