GDB - The GNU Debugger

The GNU debugger (GDB) allows a programmer to examine the internal operation of a running program. Variables and expressions can be printed and values changed. The program can be executed a line at a time or be forced to pause at specific locations. For programs that step outside the bounds of properly allocated memory, GDB can run a program while constantly watching specified memory location to see when they change. GDB is also useful to perform a post-mortem analysis of a program that has crashed and left behind a core file (more below).

GDB is best used with programs that have been compiled using the -g option. This places information in the executable code that lets the debugger know which parts of the executable correspond to which lines in source code files, which memory locations correspond to which variable names, and so forth. Programs compiled with the -g option are usually larger and slower than they would be otherwise.

GDB is used by typing in commands at a prompt. To reduce the amount of typing, most commands have abbreviations, many as small a single letter. Because some commands are used successively, GDB has the feature that when an empty command line is entered (no characters, just the return key) it will repeat the previous command. This point is important to understand in the efficient use of GDB.

The GDB commands fall naturally into several categories. An explanation of how to start gdb and a description of some of the most common commands is given below. Where they exist, the command abbreviations are given as well.

Invocation

GDB is started by typing gdb on the command line along with the name of the executable file to be debugged. If the program takes command line arguments, they are not given here. A splash message is displayed and then the GDB prompt is given, (gdb). This does not actually run the executable, but loads it in preparation for execution.

Running a Program

The commands for starting and stopping a program are given below.
r or run
This command (re)starts running the program from the beginning. If the program takes command line arguments, these are placed after the run (or r) command. GDB is smart enough to remember the command line arguments, so subsequent restarts of the program do not need to explicitly list them. For example, in the following session
	  (gdb) r arg1 arg2 arg3
	  
	  ...  More debugging session here
	  
	  (gdb) r
	
these two program restarts provide the exact same set of arguments to the program.

q or quit
This command exits the debugger.

n or next
Execute the next source code line of the program. If the next line to be executed involves a function call, then the entire function call is executed. This is similar to the "step over" feature found in other debuggers.

Every time the execution stops, the source code line of the line about to be executed is printed. Not the line that was just executed. This is one of the most common misunderstandings about any debugger.

This command takes an optional integer argument which specifies the number of steps to take.

s or step
Execute the next source code line of the program. If the next line to be executed involves a function call, then step into that function. This is similar to the "step into" feature found in other debuggers.

Using a combination of next and step commands it is possible to begin executing in the main() function of a program and then step into functions of interest, quickly arriving at a function that may be buried deep within the executing program.

It must be noted that a program can not be started using the next and step commands. If single stepping through a program from the beginning is desired, a breakpoint must be set on the main() function.

This command also takes an optional integer argument specifying the number of steps to take.

c or continue
Continue the execution of the program until the next breakpoint or the program ends.

finish
Complete execution of the current function and stop after returning. This is very useful after stepping into a function by mistake, or after having verified that the function is executing correctly.

return
Return immediately from the current function without executing the rest of the code for the function. This command takes an optional argument, which is the value to be returned. This command is useful for working around functions that are known to be defective, but must be used with caution.

bt or backtrace
Print the execution stack.

When a program stops because of a breakpoint or an error, chances are good that it is "executing" in multiple functions. Function A has called function B which in turn is calling function C which called function D when the program stopped. Did the program stop in function A, B, C or D? The answer is yes, it stopped in all of them.

When a function calls another, it is placed on a stack of executing functions. The information associated with any one function that is in the process of being executed is called a frame. The backtrace command prints out the stack frame of executing functions. This is useful in knowing exactly how the function of interest (the last one called) was called.

The execution stack has a direction. The main() function is considered to be at the top of the stack. The innermost function being executed is considered to be at the bottom.

up
Move up the execution stack.

down
Move down the execution stack. The up and down commands change the focus of the GDB commands. If a program has a serious error such as a segmentation fault, it will invariably break inside a library function, during input or output. The code at these levels can not be listed, and in any event, the problem is not likely the fault of the libraries. In order to examine the values of variables in the functions that called the library functions, it is necessary to move up the stack until the desired level has been found.

Moving up or down the stack does not execute any code in the innermost functions. In order to finish the execution of code in any given function, the finish command must be used.

Examining Data

l or list
List part of the program source code. Only 10 lines are listed. If no arguments are given to this command the current line to be executed is shown in the middle of the 10 line listing. If no arguments are given and the last command was also a list command, then the 10 lines following the lines already shown are displayed. This makes it possible to list large sections of code by using the list command multiple times. (Or by using the list command once and hitting the enter key multiple times to perform last command repetition.)

The list command takes optional arguments. Some of these (shown as examples) are

list 20
List starting at line 20.
list my_function1
List starting at the function my_function1()
list +30
List the next 30 lines. This gets around the 10 line limitation mentioned above. This default number of lines to be listed can be changed using the command set listsize 30. The current setting of the number of lines to be listed by default can be examined using the command show listsize.
list 10,75
List lines 10 through 75.

p or print expression
Print the given expression. It must be emphasized that this command is capable of printing expressions, which can be very complex. The expressions can contain multiple variables. Nearly anything that can be evaluated as a valid C or C++ expression is legal.

Only the variables that are availiable in the current function being executed can be used in expressions. This includes any global variables that are available. Variables in other functions are not available.

This command will print out as much as it intelligently can, given the type of the expression. If printing out the value of a char * it will print the value of the C style string pointed at. Arrays can be printed out as well, simply by giving the name of the array as the expression. However, this assumes that the size of the array is known, so only explicitly sized arrays can be printed out this way. Printing out a class instance will show all of the data members for that instance.

Because the print command can evaluate any C/C++ expression, it can also evaluate assignment expressions. This is how values are changed using the debugger. For example if the current function contained an integer variable a that had been assigned the value of 7, the following session fragment shows how the value of a is examined, set to have the value of 4 and re-examined:

	  (gdb) p a
	  $1 = 7
	  (gdb) p a = 4
	  $2 = 4
	  (gdb) p a
	  $3 = 4
	  (gdb) 
	  

Breakpoints

Breakpoints are places in the program being examined where the execution is forced to stop. Breakpoints can be inserted and deleted during a debugging session. No changes are made to the source code. Temporary breakpoints can also be created, which exist only until they are encountered the first time.
b or break
This command sets a breakpoint. If it is not given an argument it places the breakpoint at the current location in the code. This command can take different kinds of options, some of which are shown below as examples.
break 30
Set a breakpoint at line 30
break my_function2
Set a breakpoint at the first executable statement in the function my_function2()
break +10
Set a breakpoint 10 lines after the current position.
break 40 if *p == 'c'
Set a breakpoint at line 40 that will break only if the expression *p == 'c' evaluates to true at that point in the program. This is a very powerful form of setting breakpoints. The breakpoint position can be set using any of the forms given previously: by line number, by function name, or by relative position. The condition can be any valid C/C++ expression that evaluates to a non-zero/zero value, which is treated as true or false.

Each breakpoint is given an integer number when it is assigned. All references to a particular breakpoint are given with that number. The number is printed out when the breakpoint is assigned, but can be printed out as explained below.

tbreak
Set a temporary breakpoint. A temporary breakpoint is one that is automatically deleted when it is encoutered. This is useful for one-time situations, getting out of long loops, and the like.

Temporary breakpoints take all of the arguments for setting them that regular breakpoints take.

info break
Display all of the breakpoints set in the program. The information printed includes the breakpoint number, the location of the breakpoint, and the number of times that the breakpoint has been examined.

d or delete
If this command is given no arguments, then all breakpoints are deleted. Otherwise, this command takes a list of integer arguments, the breakpoints to be deleted.

clear
Delete any breakpoints on the next line to be executed. This command can also take arguments, which are illustrated below:
clear my_function3
Clear any breakpoints at the beginning of my_function3
clear 25
Clear any breakpoints found on line 25.

Watchpoints

Watchpoints are used to examine the value of an expression at every step of the program, stopping whenever the value of the expression changes. Watchpoints are invaluable in finding out what function is trashing a particular section of memory that should not be changing. Because the watchpoint is examined with every step of the program, watchpoints make a program hundreds or thousands of times slower. But sometimes they are the best tool for the job.
watch expression
Set a watchpoint for the expression. The program will break whenever the value of the expression changes from its current value.

Watchpoints are listed using the info break command described above.