5.6 A Unix Debugger


Presented in this section is information on how to use a source-code debugging system, gdb (the Gnu DeBugger), and xxgdb, a graphical user-interface to the gdb debugger under the X Window System. Through the graphical user interface provided by xxgdb, the developer is provided with a simple-to-use environment for debugging prgrams. The interface provides simple mechanisms for controlling program execution through breakpoints, examining and traversing the call stack, and displaying values of variables and objects. All of these operations are done at the source-code level.

Gdb has many commands, more than are covered here. For more information about gdb consult 0 Debugging with GDB, a reference manual for the gdb debugger.

To use xxgdb the program must be compiled with the g++ compiler using the "-g" compiler flag set. For example, the command:

       g++ -g -o prog prog.cc

compiles the file prog.cc. The -g flag causes the compiler to insert information into the executable file (named "prog") that gdb and xxgdb require in order to work.

Starting xxgdb

To start the xxgdb simply enter its name ("xxgdb") on the command line. A graphical display will be presented that looks like this:

From top to bottom, the xxgdb display consists of the following subwindows:

File Window
Display the full pathname of the file displayed in the source window, and the line number of the caret.
Source Window:
Shows the contents of the source file that is being debugged. The name of this file is given in the file window. In the initial window, the source window is empty except for a single caret symbol (^). During a debuggin session, the relevant source code will appear in this subwindow; tis source window will scrolled during the execution of the program so that the current line being executed is always visible.

Message Window :
This window provides information-feedback messages from the debugger relating to the execution status of the program and error messages generated by xxgdb. The message window in the initial xxgdb display shown in the figure says "Ready for execution," which is the initial state of gdb. Other status information will appear in this place throughout a session.

Command Window:
In the middle of the screen, the command window contains a set of twenty buttons for commonly used debugging commands; each button is labeled with the name of a command. To execute the command, simply click the left mouse button on the corresponding button in the command window. The meaning of each command is explained below.
Dialogue/Display Window
This window is an area for displaying outut from the program or from gdb. Alternatively, any gdb command can be entered in this window. The dialogue/display window initially contains the gdb disclaimer message, which begins with the words "GDB comes with ... "

The relative sizes of the source, command, and the dialogue/display windows can be adjusted by dragging the grip (a small square ner the right edge of the horizontal border) with the left mouse button down. During a debugging session it may be convenient to resize these windows to allow the most useful information to be seen more easily.

Selecting, Searching, and Quitting

The first category of commands are those that control the overall operation of the debugging session. The command window contains three buttons for beginning a debugging session, quitting xxgdb, and searching through the source code of the program being debugged. These buttons are:

Presents a directory navigator that allows the user to select a text file to be displayed, an executable file to debug, or a core file to debug. In the navigation display, directory entries are marked with a trailing slash (/) and executables with a trailing asterisk (*). Filenames beginning with a dot (.) or ending with a tilde (~) are not listed in the menu.
Terminates the execution of xxgdb and the program that is being debugged.

Initiates a search dialogue allowing the user to search for a given string within the file displayed in the source window. The search may go forward or backwards from the current location (indicated by the caret symbol in the source window). The carriage return is used to initiate a search and draw down the search panel.

It is important to remember that the file you select for debugging must be an executable file that has been compiled with g++ by using the "-g" compiler option.

When an executable file is selected, xxgdb loads the executable file in preparation for debuggin and it displays the source text of the file in the source window.

Setting Breakpoints

The second set of commands deal with breakpoints - designated points within the program where the program will halt and return control to the debugger, allowing the user to examine the state of the program at that point. Breakpoints are typically placed at strategic locations in the program at which the user believes the most relevant and revealing information can be obtained about the program's bug.

It is common during debugging that new breakpoints will be added and existing breakpoints deleted. As the user gains more insight into the program's execution, the places at which the most useful information can be obtained changes. New breakpoints may be added at any time that the debugger is in control (i.e., the program is halted at a breakpoint). Removing or deleting a breakpoint means that the breakpoint is remved from the program and the program will no longer halt its execution at that point.

Breakpoints can be set and deleted using the following buttons in the command window:

Insert a new breakpoint into the program. The caret symbol in the source window indicates where the breakpoint will be placed. If the caret is not at the desired breakpoint location, simply move the caret to the beginning of the source line and click on the break button. A stop sign will appear next to the source line.

Adds a special kind of breakpoint that is used only once, which means that the program's execution will halt when the flow of control next reaches this breakpoint and then the breakpoint will automatically be deleted. This cmmand is useful for setting breakpoints that are only needed temporarily.

Removes an existing breakpoint. The breakpoint that is deleted is indicated by the current placement of the caret in the source window. The breakpoint on the current source line is the one removed.

Note that is not necessary to delete a breakpoint to proceed past it. Gdb automatically ignores breakpoints on the first instruction to be executed when you continue execution without changing the execution address.

Controlling the Program's Execution

The third set of commands are those that allow the user to control the program's execution at a finer level than is efficient with breakpoints. Typically, thse commands allow the user to control the line-by-line execution of the program once a breakpoint has been reached. The relevant commands are:

Starts the program's execution immediately after it has been loaded.

Short for "continue," this command resumes the program's execution after the program has halted at a breakpoint. The program will halt when it reaches a breakpoint, completes normally, or experiences a run-tme error that would normally abort the program.
Executes one complete source statement. If the source line contains one or more method invocations, these methods are executed to completion without halting. The program will be halted when the complete source statement has completed.
Similar to the next command, step differs in how method invocations are treated. If the source statement contains a method invocation, the program is halted at the first line in the invoked method.

This command allows the program to resume execution and halt again when the current method invocation is competed. This command is typically used sometime after a step command has begun executing a method.

A typical debugging technique combines the use of breakpoints and the step/next commands to control program execution. A breakpoint is used to establish course-execution control. When halted at a breakpoint, the subsequent code is traced using the finer-grain step/next commands. As this code is being traced, the commands discussed below are used to examine the state of the system.

Examining the Execution History

The fourth set of commands allows the user to examine the state of the system being debugged. The user is to review the history of method invocations (the run-time stack) that ended in the current point of execution and the arguments and local variables of the current method, or any other method in the current history. Variables that are simpe types as well as objets of user-defined classes may be checked.

Each stack frame is assigned a simple integer number by the debugger. The current frame (the frame corresponding to the method that is currently executing) is number 0 (zero). The frame corresponding to the method that invoked the curent method is number 1, and so on. These numbers have no significance to the program; they are simply used to allow the developer to refer to a particular frame in the run-time stack. This number is used on several commands.

Most commands for examining the stack and other data in the program operate on whichever stack frame is selected at the moment. In particular, whenever gdb is asked for the value of a variable in the program, the value is that of the variable in the selected stack frame. There are special gdb commands to select a frame.

The commands related to the run-time stack are:

Displays a succinct representation of the sequence of method invocations that are on the run-time stack.
Changes the frame being examined to one level higher on the run-time stack.
Changes the frame being examined to one level lower on the run-time stack.
Shows the arguments of the method corresponding to the currently selected stack frame.

Shows the local variables of the method corresponding to the currently selected stack frame.

For the up and down commands, it is important to remember that "up" in the run-time stack advances away from the method currently being executed, backward in time, toward the outermost frame, to higher frame numbers, to frames that have existed longer. Conversely, "down" advances toward the method currently being executed, forward in time, toward the innermost frame, to lower frame numbers, to frames that were created more recently.

Examining Variables

The fifth set of commands allow the value of variables and objets to be examined. Often these values give the best evidence of the effects of the program's bug. With xxgdb, bot the values of built-in tpes (int, float, char, char*, and so on) cand the values of objects of user-defined classes can be biewed with equal ease.

The value of a variable or object can be viewed by identifying the variable or object and using one of the following command buttons:

Displays the value of a selected variable or object.
Displays the value of the variable or object that is pointed to by the selected variable.

Displays the value of a selected variable in the display window, updating its value every time execution stops.

Stops displaying the value of the selected variable in the display window. If the selected variable is a constant, it refers to the display number associated with an expression in the display window.

The value of a variable may be examined in one of several ways. In the simplest case, the variable is not a pointer and its name is visible in the source window. When this happens, simply highlight the name of the variable in the source window and press the print button. The value will appear in the dialogue/display window. If the variable is a pointer to an object, highlight the name of the pointer variable and use the print* command button. The value will, as before, appear in the dialogue/Ddsplay window. If the name of the variable is not currently visible in the source window you can type its name in the dialogue/display area, highlight the name in the dialogue/display area, and use the "print" or "print*" command buttons as before.


©1998 Prentice-Hall, Inc.
A Simon & Schuster Company
Upper Saddle River, New Jersey 07458

Legal Statement