Windows - Lab Exercise 2
Using the GDB Debugger within Emacs

Data Structures and Other Objects Using C++
by Michael Main and Walter Savitch
ISBN 0-8053-7470-1, Softcover, 784 pages, 1997


Last week you learned how to use emacs and g++ to edit and compile programs. If this editor and compiler are not installed on your machine, then you may obtain them from www.cs.colorado.edu/~main/cs1300/README.html. .

Now we would like you to learn about a debugger called gdb that you will use this semester. You may have used a similar debugger on a PC, and my guess is that the PC's debugger is a lot nicer than gdb. But by using emacs in conjunction with gdb, you do obtain a some degree of integration among your editor/compiler/debugger.

Starting the Debugger within Emacs
Today you'll just run through one introductory session, using the debugger on the heatwave.cxx program. To get the debugger started on the heatwave program, start a DOS session, change to the directory that you used in the previous exercise, and open heatwave.cxx with the emacs editor. Then recompile heatwave.cxx by giving the "ESC x compile" command. In the miniwindow, you should erase "make -k" and type this compilation command instead:

g++ -Wall -gstabs heatwave.cxx -o heatwave

The reason for recompiling is that the debugger requires the compilation to have an extra -gstabs switch. I would suggest that you use -gstabs in all your future compilations. You never know when you might need to debug! After the compilation finishes, you can start the debugger with these steps:

  1. Shut the compilation window (Ctrl-x 1, which says "give me just one window).
  2. Split the window into two (Ctrl-x 2). Both the top and bottom window will have heatwave.cxx.
  3. Move the cursor to the "other" window (Ctrl-x o). The cursor should now be in the bottom window.
  4. Start the debugger with the command: "ESCAPE x gdb RETURN". The miniwindow will print a small prompt "Run gdb (like this): gdb". You should type the name of the executable file, as shown here:

    Run gdb (like this): gdb heatwave

    Then press return, and the gdb debugger starts in the bottom window.

Setting and Removing Breakpoints
When the debugger starts, the bottom screen prints a message and the prompt (gdb). With the cursor at this prompt, you can give commands to the debugger, and there are also a few special emacs commands that you can give while the debugger is running. We'll start by setting a breakpoint at the start of the main program. A breakpoint is just a line of code where the program's execution will stop. I like to stop at the beginning of the main program so that I can assess my situation and proceed from there. Here's how to set or remove a breakpoint:
  1. Move to the code window (use "Ctrl-x o" to move to the other window if you are not already in the code window).
  2. Move the cursor desired line in the program. In this case, you should move down to the beginning of the first cout statement in the main program.
  3. Ctrl-x SPACE (that is, Ctrl-x and then the space bar).
You'll see a message about the breakpoint appear in the bottom window. Or you might get an error message saying that there is no source file HEATWAVE.CXX. If you get this error message, the problem is that the file has been recorded as HEATWAVE.CXX (all capitals) but it should be heatwave.cxx (lower case). To fix this problem, quit emacs and give the rename command:
    rename HEATWAVE.CXX heatwave.cxx

Later, if you need to remove the breakpoint, move the cursor back to this line, and give the "remove breakpoint" command (Ctrl-x Ctrl-a Ctrl-d).

An alternative to "Ctrl-x SPACE" is "Ctrl-x Ctrl-a Ctrl-t", setting a temporary breakpoint (which will be removed the first time it is used).

Running the Program
Once the breakpoint is set, you can run your program. Of course, it won't run very far, since there is a breakpoint at the top of the program. Move to the bottom window and type the word "run" at the (gdb) prompt, and press return. You might get a few warnings or messages about Windows DLLs. Then you'll see messages like this:

Breakpoint 1, main () at heatwave.cxx:40
(gdb)

This message means that your program ran until it reached "Breakpoint 1", which was in the main() function on line 40 of heatwave.cxx. If you look in the code window at the top, you'll see that emacs placed an arrow on line 40 to indicate where the breakpoint occurred.

The prompt (gdb) in the bottom window means that the debugger is ready for you to issue another command. You can proceed in many ways. You can examine the values of variables, you can look at the runtime stack (which indicates the current sequence of function calls), you can continue executing the program. For now, you should continue executing the program by typing "cont" and pressing return. You will get the message "Continuing," and the program will execute its dialog with you. You should answer all of the program's questions until execution ends. At the end you see the message "Program exited normally" and the (gdb) prompt appears once more.

Display, Next, Print, Step
The display command allows you to display the current values of particular variables. To see how the display works, you should first restart your program, by typing the run command once again. We'll run through the program in a slightly different way, displaying the value of the variable height. In order to display this variable, type the command "display height" in the gdb window. You'll get a response such as "height=0", or maybe "height=42" or "height=126429"--you really don't know what value height will have right now because it hasn't yet been given a value.

Now we will continue executing the program, but we'll execute only one line at a time. In order to execute one line at a time, type "next" command in the gdb window and press return. Type this command once now. The next statement of your program is executed! In this program, that statement is an output statement, and the output message "How tall is your tree in feet?" appears in the gdb window. In the code window, the arrow has moved down one statement to indicate the current location of the execution.

Gdb also keeps you updated on the value of the display variable (height), which has not changed since the last time it was displayed. Finally, the (gdb) prompt appears again, indicating that the debugger is ready for another command.

At this point, you should give another next command and press return. The cursor will move to the next line and just sit there. Why did this happen? Has the debugger crashed? No! You see, the next statement of the program is an input statement to read the value of height. The program is waiting for you to type that input. Go ahead and type a number now, and press return. When you press return, the number is read, the new value of height is displayed, and the (gdb) prompt appears once more. Also, the arrow in the code window has moved down to the next statement.

Let's add one more variable to the display. Type "display volume" and press return. At this point, the volume just contains garbage because the program has not yet assigned a value to the volume. Now, continue executing the program one statement at a time, and stop when the volume does change. Keep in mind that when the (gdb) prompt appear, you must type a debugger command. When the cursor just sits on the left with no prompt, you must not type input for the program. Also, keep an eye on the arrow in the code window to see which statements are about to be executed.

After the volume changes to its new value, give the cont command to execute the remainder of the program.

There are three other commands that you will find useful: (1) undisplay followed by a number n will remove item n from the display list. (2) print followed by an expression will evaluate and print the expression once (without adding it to the display list). (3) step is similar to "next", executing one statement. The difference is that the step command tries to step into the body of each function, and execute the lines of each function one at a time. Since heatwave has no functions, we're using next. (Also, step would cause problems with heatwave, since the debugger would try to step into the input >> and output << functions.)

Quitting and More About Gdb
To end gdb, type the quit command, press return, move the cursor to the top window (Ctrl-x o) and set things to just one window (Ctrl-x 1). As the semester progresses, you'll learn a lot more about gdb. You can also print the gdb reference card at www.cs.colorado.edu/~main/lab/refcard.html . For now however, the few commands that you know should be sufficient.


Michael Main (main@colorado.edu)