Previous Page
Next Page

20.4. Using GDB Commands

Upon starting, the debugger prompts you to enter commandsfor example, to set a breakpoint and run the program that you specified on the command line to load for debugging.

Each command you issue to GDB is a line of text beginning with a command keyword. The remainder of the line consists of the command's arguments. You can truncate any keyword, as long as you type enough of it to identify a command unambiguously. For example, you can enter q (or qu or qui) to exit the debugger with the quit command.

If you enter an empty command linethat is, if you press the return key immediately at the GDB command promptthen GDB repeats your last command, if that action is plausible. For example, GDB automatically repeats step and next commands in this way, but not a run command.

If you enter an ambiguous or unknown abbreviation, or fail to specify required command arguments, GDB responds with an appropriate error message, as in this example:

(gdb) sh
Ambiguous command "sh": sharedlibrary, shell, show.

20.4.1. Command Completion

The GDB debugger can reduce your typing by completing the names of commands, variables, files, and functions. Type the first few characters of the desired word, then press the Tab key. For example, the program circle.c in Example 1-1 contains the function circularArea( ). To display this function in a GDB session, all you have to enter is the following:

(gdb) list ci

and press the Tab key. Automatic completion yields this command line:

(gdb) list circularArea

Press Return to execute the command. If there are several possible completions for a word, GDB inserts the next letters that are common to all possible completions, then prompts you for more input. You can type another letter or two to make your entry more specific, then press the Tab key again. If you press the Tab key twice in a row, GDB displays all possible completions of the word. Here is an example of command completion in several steps:

(gdb) break ci<tab>

GDB appends two letters, then pauses for more input to resolve an ambiguity:

(gdb) break circ

If you press the Tab key twice, GDB displays the possible completions, then repeats the prompt:

(gdb) break circ<tab><tab>
circle.c      circularArea
(gdb) break circ

20.4.2. Displaying Help for Commands

GDB has a help function, which divides its many commands into classes to help you find the one you need. When you enter the help (or h) command with no argument, GDB prints the list of command classes:

(gdb) h
List of classes of commands:
aliases -- Aliases of other commands
breakpoints -- Making program stop at certain points
data -- Examining data
files -- Specifying and examining files
internals -- Maintenance commands
obscure -- Obscure features
running -- Running the program
stack -- Examining the stack
status -- Status inquiries
support -- Support facilities
tracepoints -- Tracing of program execution without stopping the program
user-defined -- User-defined commands
 
Type "help" followed by a class name for a list of commands in that class.
Type "help" followed by command name for full documentation.
Command name abbreviations are allowed if unambiguous.
(gdb)

To read about the commands in a given class, type help followed by the class name. To read about how a given command works, enter help followed by the name of the command.

20.4.3. Status Information

To display information about the status of the debugger and the program being debugged, GDB provides the commands info and show, as the help text shows:

(gdb) help status
Status inquiries.
List of commands:
info -- Generic command for showing things about the program being debugged
show -- Generic command for showing things about the debugger

20.4.3.1. Status information on the program being debugged

The info command with no argument lists all the items that you can query about the program you are testing:

(gdb) info
List of info subcommands:
 
info address -- Describe where symbol SYM is stored
info all-registers -- List of all registers and their contents
info args -- Argument variables of current stack frame
info breakpoints -- Status of user-settable breakpoints
...

When you specify one of the info arguments listed, GDB displays the corresponding information. Like commands, these arguments can be abbreviated, as in the following command:

(gdb) info all-reg

This command displays the contents of all processor registers, including floating-point and vector registers. The command info register, on the other hand, displays only the CPU registers, without the floating-point or vector registers.

The following command displays information about the current source file; that is, the source file containing the function which is currently being executed. If you have not yet started the program that you want to test, then the current source file is the one that contains the function main( ):

(gdb) info source
Current source file is circle.c
Compilation directory is /home/peter/C_in_a_Nutshell/tests/Ch20/
...
(gdb)

Some of the subcommands take another argument. For example, the info subcommand address in the following example takes the name of an object or function as its argument:

(gdb) info address radius
Symbol "radius" is a local variable at frame offset -8.
(gdb)

20.4.3.2. Status information on the debugger

Like info, the show command also has numerous subcommands, to display various kinds of information about the debugger itself. The help text on show describes its subcommands:

(gdb) help show
Generic command for showing things about the debugger.
List of show subcommands:
 
show annotate -- Show annotation_level
show archdebug -- Show architecture debugging
show architecture -- Show the current target architecture
show args -- Show argument list to give program being debugged when it is started
...

The following command displays information about GDB's current logging behavior:

(gdb) show logging
Future logs will be written to gdb.txt.
Logs will be appended to the log file.
Output will be logged and displayed.
(gdb)

Most of the settings displayed by show can be modified by the set command. For example, the following command turns on logging:

(gdb) set logging on
Copying output to gdb.txt.
(gdb) show logging
Currently logging to "gdb.txt".
...

The online help also describes the subcommands. For example, the following help command displays a description of possible logging settings:

(gdb) help set logging

20.4.4. Running a Program in the Debugger

The following GDB commands allow you to control programs running in the debugger:


file filename

If you have not specified the program you want to debug in the GDB command line, you can indicate it at GDB's prompt using the file command. GDB reads the symbol table from the executable file filename, and starts the program if you enter a subsequent run command. If filename is not in the debugger's working directory, the debugger searches for it in the directories named in the environment variable PATH.


set args [ arguments]

If you have not specified the command-line arguments for the program you want to debug in the GDB command line, you can define them at GDB's prompt using the set args command. For example, the following command specifies two arguments for the program being tested:

(gdb) set args -d $HOME

To clear the argument list without setting new arguments, enter the set args command with no further arguments.


show args

Displays the currently set command-line arguments for the program being debugged:

(gdb) show args
Argument list to give program being debugged when it is started is "-d $HOME".


run [ arguments]

When you start a program using the run command (r for short), you can also specify command line arguments for it. On Unix-like systems, the arguments may contain shell metacharacters such as * and $. You can also redirect the program's input and output using <, >, and >>. The debugger uses a shell to interpret the program's command line, so that all special characters have the same effect as they would in an ordinary shell environment. GDB uses whichever shell is indicated by the SHELL environment variable, or the default shell /bin/sh if SHELL is not defined.

The run command with no arguments starts the program with the arguments currently set for it in GDB. If you have not yet set any arguments for the program, whether in a previous run command, on the GDB command line, or in a set args command, then run starts the program with no arguments.

Once you start the program using the run command, it runs until it exits, or until it reaches a breakpoint that you have set in the debugger. The program can also be interrupted by a signal, such as the SIGINT signal, which is usually raised by the key combination Ctrl+C.


kill

If you have found one or more errors to correct and want to edit and recompile a program outside the debugger, you should first terminate it. You can do this using the kill command, as in the following example:

(gdb) kill
Kill the program being debugged? (y or n) y

The settings, including the command-line arguments for the program, remain unchanged as long as you do not exit the debugger. The next time you start the program using the run command, GDB detects the fact that the executable file has been modified, and reloads it.

20.4.5. Displaying Source Code

You can display a program's source code in the debugger using the list (or l) command. By default, GDB displays ten lines at a time, starting five lines before the next statement to be executed. The list command supports arguments that allow you to specify which part of the program you want to display:


list filename: line_number

Displays source code centered around the line with the specified line number.


list line_number

If you do not specify a source filename, then the lines displayed are those in the current source file.


list from,[ to]

Displays the specified range of the source code. The from and to arguments can be either line numbers or function names. If you do not specify a to argument, list displays the default number of lines beginning at from. For example, the following command displays the first 10 lines of the main( ) function:

(gdb) list main,


list function_name

Displays source code centered around the line in which the specified function begins.


list, l

The list command with no arguments displays more lines of source code following those presented by the last list command. If another command executed since the last list command also displayed a line of source code, then the new list command displays lines centered around the line displayed by that command. For example, if the debugger has just interrupted execution of the program at a breakpoint, the next list command displays lines centered around that breakpoint.

If you have not yet started the program, the first list command with no arguments displays source code centered around the beginning of the main( ) function, as the following example illustrates:

$ gdb -silent circle
(gdb) l
1    // Circle.c: Calculate and print the areas of circles
2    #include <stdio.h>                // Preprocessor directive
3
4    double circularArea( double r );  // Function declaration (prototype
5                                      // form)
6    int main( )                        // Definition of main( ) begins
7    {
8      double radius = 1.0, area = 0.0;
9
10     printf( "    Areas of Circles\n\n" );
(gdb)

Two other commands are useful in controlling the output of your list commands:


set listsize number

Sets the default number of lines displayed by list commands to number.


show listsize

Shows the default number of lines displayed by list commands.

20.4.6. Working with Breakpoints

On reaching a breakpoint, the debugger interrupts the running program and displays the line at which you have set the breakpoint. To be exact, the line displayed is the line containing the next statement that will be executed when the program resumes. Once the program flow has been interrupted by a breakpoint, you can use GDB commands to execute the program line by line, and to display the contents of variables and registers.

Breakpoints can also be made conditional, so that on reaching such a breakpoint, the debugger interrupts the program only if a specified condition is fulfilled.

20.4.6.1. Setting and displaying breakpoints

Set breakpoints using the break command, which you can also abbreviate b. You can specify the location of a breakpoint in several ways. Here are the most common forms of the break command:


break [ filename:] line_number

Sets a breakpoint at the specified line in the current source file, or in the source file filename, if specified.


break function

Sets a breakpoint at the first line of the specified function.


break

Sets a breakpoint at the next statement to be executed. In other words, the program flow will be automatically interrupted the next time it reaches the point where it is now. (To be more exact, the break command with no arguments sets a breakpoint at the next statement in the currently selected stack frame: see the section "Analyzing the Stack," later in this chapter. For now, we assume that you have not explicitly selected any stack frame, so that the current frame corresponds to the function in which the program flow is currently interrupted, and the break command with no arguments sets a breakpoint at the current statement.)

Referring now to the program gdb_example.c from Example 20-1, the following command sets a breakpoint at the beginning of the function swap( ):

(gdb) b swap
Breakpoint 1 at 0x4010e7: file gdb_example.c, line 27.

The output from the b command tells you that the breakpoint was set on line 27. You can issue the list command to confirm that line 27 is, in fact, the first line of the swap function:

(gdb) list 27
22          return 0;
23      }
24
25       void swap( int *p1, int *p2 )         // Exchange *p1 and *p2.
26      {
27         int *p = p1;
28         p1 = p2;
29         p2 = p;
30      }
31

The following command sets a second breakpoint before the end of the function:

(gdb) b 30
Breakpoint 2 at 0x4010f9: file gdb_example.c, line 30.

You can use the info command to display all the breakpoints that are currently defined:

(gdb) info breakpoints
Num Type           Disp Enb Address    What
1   breakpoint     keep y   0x004010e7 in swap at gdb_example.c:27
2   breakpoint     keep y   0x004010f9 in swap at gdb_example.c:30

The breakpoint numbers shown at left in the info output are used to identify the individual breakpoints in other commands, such as those to delete or disable a breakpoint. In the info output above, the letter y for "yes" in the column labeled Enb indicates that both breakpoints are enabled. The third column, labeled Disp for "disposition," indicates whether each breakpoint will be retained or deleted the next time the program flow reaches it. If a breakpoint is temporary, GDB automatically deletes it as soon as it is reached. To set a temporary breakpoint, use the tbreak command instead of break, as in the following example:

(gdb) tbreak 16
Breakpoint 3 at 0x4010c0: file gdb_example.c, line 16.

20.4.6.2. Deleting, disabling, and ignoring breakpoints

The following commands take as their argument either a single breakpoint number or a range of breakpoints. A range consists of two breakpoint numbers separated by a hyphen, such as 3-5.


delete [ bp_number | range]


d [ bp_number | range]

Deletes the specified breakpoint or range of breakpoints. A delete command with no argument deletes all the breakpoints that have been defined. GDB prompts you for confirmation before carrying out such a sweeping command:

(gdb) d
Delete all breakpoints? (y or n)


disable [ bp_number | range]

Temporarily deactivates a breakpoint or a range of breakpoints. If you don't specify any argument, this command affects all breakpoints. It is often more practical to disable breakpoints temporarily than to delete them. GDB retains the information about the positions and conditions of disabled breakpoints so that you can easily reactivate them.


enable [ bp_number | range]

Restores disabled breakpoints. If you don't specify any argument, this command affects all disabled breakpoints.


ignore bp_number iterations

Instructs GDB to pass over a breakpoint without stopping a certain number of times. The ignore command takes two arguments: the number of a breakpoint, and the number of times you want it to be passed over.

Here is an example using all of the commands listed:

(gdb) del 2
(gdb) dis 1-3
No breakpoint number 2.
(gdb) ena 1
(gdb) ign 1 5
Will ignore next 5 crossings of breakpoint 1.
(gdb) info b
Num Type           Disp Enb Address    What
1   breakpoint     keep y   0x004010e7 in swap at gdb_example.c:21
        ignore next 5 hits
3   breakpoint     del  n   0x004010c0 in main at gdb_example.c:14

As the info output indicates, breakpoint 2 no longer exists; the temporary breakpoint 3 is disabled, and breakpoint 1 will not stop the program until the sixth time the program reaches it.

20.4.6.3. Conditional breakpoints

Normally, the debugger interrupts a program as soon as it reaches a breakpoint. If the breakpoint is conditional, however, then GDB stops the program only if the specified condition is true. You can specify a break condition when you set a breakpoint by appending the keyword if to a normal break command:

break [position] if expression

In this syntax, position can be a function name or a line number, with or without a filename, just as for an unconditional breakpoint (see the earlier subsection "Setting and displaying breakpoints"). The condition can be any C expression with a scalar type, and may include function calls. Here is an example of a conditional breakpoint:

(gdb) s
27      for ( i = 1; i <= limit ; ++i )
(gdb) break 28 if i == limit - 1
Breakpoint 1 at 0x4010e7: file gdb_test.c, line 28.

This command instructs the debugger to interrupt the program at line 28 if the variable i at that point has a value one less than the variable limit.

Any variables you use in a break condition must be visible at the breakpoint's position. In other words, the breakpoint must be located within the variables' scope.


If you have already set a breakpoint at the desired position, you can use the condition command to add or change its break condition:

condition bp_number [expression]

The argument expression becomes the new condition of the breakpoint with the number bp_number. The output of the info breakpoints (or info b) command includes any break conditions, as the following example illustrates:

(gdb) condition 2 *p1 != *p2
(gdb) info b
Num Type           Disp Enb Address    What
1   breakpoint     keep y   0x004010ae in main at gdb_example.c:12
2   breakpoint     keep y   0x004010e7 in swap at gdb_example.c:21
        stop only if *p1 != *p2
3   breakpoint     del  y   0x004010f9 in swap at gdb_example.c:24
(gdb)

To delete a break condition, use the condition command without an expression argument:

(gdb) condition 2
Breakpoint 2 now unconditional.

20.4.7. Resuming Execution After a Break

When you have finished analyzing the state of a stopped program, there are several ways of resuming execution. You can step through the program line by line, or let the program run to the next breakpoint, or let it run to a specified position, such as the end of the current function. The commands you can use to proceed after a break in execution are listed here. Examples of all four commands are given after the list.


continue [ passes] , c [ passes]

Allows the program to run until it reaches another breakpoint, or until it exits if it doesn't encounter any further breakpoints. The passes argument is a number that indicates how many times you want to allow the program to run past the present breakpoint before GDB stops it again. This is especially useful if the program is currently stopped at a breakpoint within a loop. See also the ignore command, described in the previous section "Working with Breakpoints."


step [ lines] , s [ lines]

Executes the current line of the program, and stops the program again before executing the line that follows. The step command accepts an optional argument, which is a positive number of source code lines to be executed before GDB interrupts the program again. However, GDB stops the program earlier if it encounters a breakpoint before executing the specified number of lines. If any line executed contains a function call, step proceeds to the first line of the function body, provided that the function has been compiled with the necessary symbol and line number information for debugging.


next [ lines] , n [ lines]

Works the same way as step, except that next executes function calls without stopping before the function returns, even if the necessary debugging information is present to step through the function.


finish

To resume execution until the current function returns, use the finish command. The finish command allows program execution to continue through the body of the current function, and stops it again immediately after the program flow returns to the function's caller. At that point, GDB displays the function's return value in addition to the line containing the next statement.

Remember that the lines of a program are not always executed in the order in which they appear in the source code. For example, consider the following function to compute a factorial:

(gdb) list factorial
21
22    // factorial( ) calculates n!, the factorial of a nonnegative number n.
23    // For n > 0, n! is the product of all integers from 1 to n inclusive.
24    // 0! equals 1.
25
26    long double factorial( register unsigned int n )
27    {
28      long double f = 1;
29      while ( n > 1 )
30        f *= n--;
31      return f;
32    }

The following excerpt of a GDB session demonstrates that lines of code can execute outside of their linear order. The frame command shows that the program execution has been stopped at line 30. The step command executes line 30, whereupon line 29 is displayed as the next one to be executed:

(gdb) frame
#0  factorial (n=10) at factorial.c:30
30         f *= n--;
(gdb) s
29       while ( n > 1 )
(gdb)

In this particular example, the execution of line 31 does not follow that of line 30. Instead, line 29 follows line 30. The reason, of course, is that the loop condition has to be evaluated after every iteration of the loop body.

If any line executed by a step command contains a function call, and GDB has the necessary symbol table and line number information for the function, then execution stops again at the first line within the function called. In the following example, the step command enters the factorial( ) function, but not the printf( ) function:

(gdb) frame
#0  main ( ) at factorial.c:14
14       printf( "%u factorial is %.0Lf.\n", n, factorial(n) );
(gdb) s
factorial (n=10) at factorial.c:28
28       long double f = 1;
(gdb)

In this example, the function printf( ), unlike factorial( ), was linked into the program from a standard library that was compiled without debugging information. As a result, GDB is able to display the contents of factorial( ), but not of printf( ).

You can use the next command to skip over function calls; that is, to avoid stepping into functions. The following example is the same as the preceding one, except that it substitutes next for step to illustrate the difference in behavior between the two commands:

(gdb) frame
#0  main ( ) at factorial.c:14
14       printf( "%u factorial is %.0Lf.\n", n, factorial(n) );
(gdb) n
10 factorial is 3628800.
16       return 0;
(gdb)

As you can see, the use of next prevented the debugger from stepping into either factorial( ) or printf( ).

Finally, here is an example illustrating the finish command, again using the factorial( ) function:

(gdb) s
14       printf( "%u factorial is %.0Lf.\n", n, factorial(n) );
(gdb) s
factorial (n=10) at factorial.c:28
28       long double f = 1;
(gdb) finish
Run till exit from #0  factorial (n=10) at factorial.c:28
0x0040112b in main ( ) at factorial.c:14
14       printf( "%u factorial is %.0Lf.\n", n, factorial(n) );
Value returned is $2 = 3628800
(gdb)

In this case, finish caused execution to continue until the return from the factorial( ) function call. (If there had been breakpoints within the factorial( ) function block, GDB would have stopped the program there.) The call to printf( ) has not yet been executed at this point, however.

20.4.8. Analyzing the Stack

The call stack , usually simply called the stack, is an area of memory organized on the LIFO principle: "last in, first out." Each time a program performs a function call, it creates a data structure on the stack called a stack frame. The stack frame contains not only the caller's address and register values, which enable the program to return control to the caller after completing the function, but also the function's parameters and local variables. When a function returns, the memory that its stack frame occupied is free again.

20.4.8.1. Displaying a call trace

When the debugger stops a program, it is often helpful to know what sequence of function calls has brought the flow of execution to the current position. GDB provides this information in the form of a call trace, which shows each function call that is currently in progress, with its arguments. To display the call trace, use the backtrace command (abbreviated bt). The backtrace command has two more synonyms: where and info stack (or info s).

The following example shows the call trace when the program circle.c is stopped within the function circularArea( ):

(gdb) bt
#0  circularArea (r=5) at circle.c:30
#1  0x0040114c in main ( ) at circle.c:18

The trace shows that the circularArea( ) function is called from main( ) at line 18, with the argument value 5. The debugger numbers the stack frames from last to first, so that the current function's frame always has the number 0. The highest numbered stack frame is that of the main( ) function.

The address that follows the frame number in the backtrace output is the return address; that is, the address of the next instruction to be executed after the return from the function call for which the stack frame was generated. However, this address is omitted from the stack frame display if it corresponds to the same source code line at which the program is stopped.

We'll illustrate backtraces using the following recursive function named factorial( ):

34    long double factorial( register unsigned int n)
35    {
36       if ( n <= 1 )
37           return 1.0L;
38       else
39           return n * factorial( n-1 );
40    }

The following GDB output shows the call stack during the final, recursive call to factorial( ). By definition, that final call occurs when n is 1. To stop the program in the last recursive iteration of the factorial( ) function, we can set a breakpoint with the condition n == 1:

(gdb) b factorial if n == 1
Breakpoint 1 at 0x40114f: file factorial.c, line 36.
(gdb) r
...
Breakpoint 1, factorial (n=1) at factorial.c:36
36         if ( n <= 1 )
(gdb) bt
#0  factorial (n=1) at factorial.c:36
#1  0x0040117c in factorial (n=2) at factorial.c:39
#2  0x0040117c in factorial (n=3) at factorial.c:39
#3  0x0040117c in factorial (n=4) at factorial.c:39
#4  0x0040117c in factorial (n=5) at factorial.c:39
#5  0x0040112b in main ( ) at factorial.c:14
(gdb)

The backtrace in this example shows that the main( ) function started things off by requesting the value of 5! (the factorial of 5). The factorial( ) function then recursively invoked itself to compute 4!, and then 3!, followed by 2!, and finally by 1!.

20.4.8.2. Displaying and changing the current stack frame

Most of the commands for examining the stack operate on the current stack frame. For example, you can address the local variables in the current stack frame by their names. When multiple frames are available, GDB lets you choose among them.

When the debugger stops the program at a breakpoint, the current stack frame is the frame corresponding to the function currently being executedthat is, the frame numbered 0 in the backtrace list. The frame command allows you to display the current stack frame, or to select a different frame:

frame [number]

The command frame, abbreviated as f, selects and displays the frame with the specified number. That frame is then the current stack frame. The frame command with no argument simply displays information about the current frame.

The output of the frame command always consists of two lines of text: the first contains the name of the function called and the values of its arguments; the second is the current source code line in the corresponding function.

In the following example, the program circle has been stopped in the function circularArea( ):

(gdb) bt
#0  circularArea (r=5) at circle.c:27
#1  0x0040114c in main ( ) at circle.c:18
(gdb) f 1
#1  0x0040114c in main ( ) at circle.c:18
18        area = circularArea( radius );
(gdb) p radius
$1 = 5
(gdb)

The command f 1 selects the stack frame that contains the call to the current function. In this example, that is the frame corresponding to the main( ) function. Once that stack frame has been selected, local variables in main( ) can be accessed by their names, as the command p radius demonstrates.

20.4.8.3. Displaying arguments and local variables

The info command has three subcommands that are useful in displaying the contents of the current stack frame:


info frame

Displays information about the current stack frame, including its return address and saved register values.


info locals

Lists the local variables of the function corresponding to the stack frame, with their current values.


info args

List the argument values of the corresponding function call.

In the following example, the program has been stopped at the beginning of the swap( ) function. This swap( ) is the corrected version of the function in Example 20-1:

25    void swap( int *p1, int *p2 )         // Exchange *p1 and *p2.
26    {
27       int tmp = *p1;
28       *p1 = *p2;
29       *p2 = tmp;
30    }

On an Intel-based system with Windows XP, the info frame command displays the following information:

(gdb) info frame
Stack level 0, frame at 0x22f010:
 eip = 0x4010e7 in swap (gdb_example.c:27); saved eip 0x4010c0
 called by frame at 0x22f030
 source language c.
 Arglist at 0x22f008, args: p1=0x22f024, p2=0x22f020
 Locals at 0x22f008, Previous frame's sp is 0x22f010
 Saved registers:
  ebp at 0x22f008, eip at 0x22f00c

The register eip (the "extended instruction pointer") contains the address of the next machine instruction to be executed, corresponding to line 27. The ebp register ("extended base pointer") points to the current stack frame. The info args command produces the following display:

(gdb) info args
p1 = (int *) 0x22f024
p2 = (int *) 0x22f020

GDB indicates the pointers' type, int *, as well as their values. The info locals command displays the following information:

(gdb) info locals
tmp = 0

20.4.9. Displaying Data

Usually you can use the print command to display the values of variables and other expressions. In addition, you can use the command x to examine unnamed blocks of memory.

20.4.9.1. Displaying values of expressions

The print or p command takes any C expression as its argument:

p [/format] [expression]

This command evaluates expression and displays the resulting value. A print command with no expression argument displays the previous value again, without reevaluating the previous expression. If you want, you can specify a different output format.

The optional argument /format allows you to specify an appropriate output format for the expression (see the following subsection, "Output formats"). Without a format argument, print formats the output as appropriate for the data type.

Expressions in print commands can also have side effects, as the following example illustrates. The current stack frame is that of the circularArea( ) function in the circle program:

(gdb) p r
$1 = 1
(gdb) p r=7
$2 = 7
(gdb) p r*r
$3 = 49

In this example, the expression r=7 in the second print command assigns the value 7 to the variable r. You can also change the value of a variable using the set command:

(gdb) set variable r=1.5

The print command's output displays an expression's value as the value of a variable $i, where i is a positive integer. You can refer to these variables in subsequent commands, as in the following example:

(gdb) p  2*circularArea($2)
$4 = 307.87608005280003

This command calls the function circularArea( ) with the value of $2 (which was 7 in our preceding example), then multiplies the return value by 2 and saves the result in the new variable $4.

You can also use the p and set commands to define new variables in GDB, with names that start with a dollar sign. For example, the command set $var = *ptr creates a new variable named $var and assigns it the value currently referenced by the pointer ptr. The debugger's variables are separate from those of the program being debugged. GDB also stores the values of CPU registers in variables whose names are the standard register names, with the dollar sign prefix.

To access variables in other stack frames without first changing the current stack frame, prefix the function name and the double-colon operator (::) to the variable's name, as the following example illustrates:

(gdb) p main::radius
$8 = 1

20.4.9.2. Output formats

The optional /format argument to the print command consists of a slash followed by a single letter that specifies an output format. The letters permitted are mostly similar to the conversion specifiers in the format string argument of the C function printf( ). For example, the command print /x displays the previous value as an integer in hexadecimal notation.

The print command converts the value to the appropriate type, if necessary. The following list describes all of the format options for integer values:


d

Decimal notation. This is the default format for integer expressions.


u

Decimal notation. The value is interpreted as an unsigned integer type.


x

Hexadecimal notation.


o

Octal notation.


t

Binary notation. Do not confuse this with the x command's option b for "byte," described in the next subsection.


c

Character, displayed together with the character code in decimal notation.

As the following example illustrates, the format option can follow the p command immediately, without an intervening space:

(gdb) p/x 65
$10 = 0x41
(gdb) p/t
$11 = 1000001
(gdb) p/c
$12 = 65 'A'
(gdb) p/u -1
$13 = 4294967295

Each print command without an expression argument in this example displays the same value as the previous command, but formatted as specified by the /format argument.

The print command accepts two more format options for non-integer expressions:


a

Displays an address, such as a pointer value, in hexadecimal notation, along with its offset from the nearest named address below it in memory, if any.


f

Interprets the bit pattern of the expression's value as a floating-point number, and displays it.

Here are some examples using these format options:

(gdb) p/a 0x401100
$14 = 0x401100 <swap+31>
(gdb) p/f 123.0
$15 = 123
(gdb) p/f 123
$16 = 1.72359711e-43

20.4.9.3. Displaying memory blocks

The x command allows you to examine unnamed memory blocks. The command's arguments include the block's beginning address and size, and an optional output format:

x [/nfu] [address]

This command displays the contents of the memory block starting at the specified address, with the block size and output format determined by the /nfu option. The address argument can be any expression whose value is a valid address. If you omit the address argument, the x command displays the next memory block following the last memory location displayed by an x or print command.

The /nfu argument can consist of up to three parts, all of which are optional:


n

A decimal number specifying how many units of memory to display. The size of each such unit is determined by the third part of the /nfu option, u. The default value of n is one.


f

A format specifier, which may be one of those supported by the print command (described in the preceding section, "Output formats"), or one of the following two additional format specifiers:


s

Display the data at the specified address as a null-terminated string.


i

Display machine instructions in assembly language.

The default format is initially x, and later whichever format you last specified in an x or print command.


u

The third part of the /nfu argument, the u option, defines the size of each memory unit displayed, and can have one of the following values:


b

One byte


h

Two bytes (a "half word")


w

Four bytes (a "word")


g

Eight bytes (a "giant word")

The default value of u is initially w, and later whichever unit you last specified in an x command. It makes no sense to specify a unit size with the format option s or i. If you do so, GDB ignores the unit size option.

The following examples illustrate the use of the x command. In these examples, assume that the following variables are defined in the current scope:

char msg[100] = "Hello world!\n";
char *cPtr = msg + 6;

Each line of the x command's output begins with the starting address of the memory location displayed, and the corresponding name from the symbol table, if any. The first x command displays the string msg:

(gdb) x/s msg
0x402000 <msg>:  "Hello world!\n"

The next command displays the first 15 bytes of the msg string in hexadecimal:

(gdb) x/15xb msg
0x402000 <msg>:  0x48   0x65   0x6c   0x6c   0x6f   0x20   0x77   0x6f
0x402008 <msg+8>:       0x72   0x6c   0x64   0x21   0x0a   0x00   0x00

Two 32-bit words, in hexadecimal notation, at the address msg:

(gdb) x/2xw msg
0x402000 <msg>: 0x6c6c6548      0x6f77206f

The string that begins at the pointer value of cPtr:

(gdb) x/s cPtr
0x402006 <msg+6>:   "world!\n"

Beginning at the same address, eight decimal character codes, with the corresponding character values:

(gdb) x/8cb cPtr
0x402006 <msg+6>: 119 'w' 111 'o' 114 'r' 108 'l' 100 'd' 33 '!' 10 '\n' 0 '\0'

The value of the pointer cPtr itself, in hexadecimal and in binary:

(gdb) x/a &cPtr
0x22f00c:       0x402006 <msg+6>
(gdb) x/tw &cPtr
0x22f00c:       00000000010000000010000000000110

20.4.10. Watchpoints: Observing Operations on Variables

GDB lets you take notice of read and write access to variables by setting watchpoints . A watchpoint is like a breakpoint, except that it is not bound to a specific line of source code. If you set a watchpoint for a variable, then GDB stops the program whenever the value of the variable changes. In fact, GDB can watch not only individual variables, but also expressions. You can set different kinds of watchpoints using the commands watch, rwatch, and awatch. All three commands have the same syntax:


watch expression

The debugger stops the program when the value of expression changes.


rwatch expression

The debugger stops the program whenever the program reads the value of any object involved in the evaluation of expression.


awatch expression

The debugger stops the program whenever the program reads or modifies the value of any object involved in the evaluation of expression.

The most common use of watchpoints is to observe when the program modifies a variable. When a watched variable changes, GDB displays the variable's old and new values, and the line containing the next statement to be executed. To illustrate the use of watchpoints, we will provide some examples based on the following simple program:

1       #include <stdio.h>
2
3       int main( )
4       {
5           int a = 10;
6           int b = 20;
7           int *iPtr = &a;
8
9           ++*iPtr;
10          puts( "This is the statement following ++*iPtr." );
11
12          printf( "a = %d;  b = %d.\n", a, b );
13          return 0;
14      }

Before you can set a watchpoint for a local variable, you must begin executing the program until the program flow enters the scope of the desired variable. For this reason, we will start by running the program to an ordinary breakpoint at line 9:

(gdb) b 9
Breakpoint 1 at 0x4010ba: file myprog2.c, line 9.
(gdb) r
Starting program: ...
 
Breakpoint 1, main ( ) at myprog2.c:9
9           ++*iPtr;

Now we can set a watchpoint for the variable a, and continue execution:

(gdb) watch a
Hardware watchpoint 2: a
(gdb) c
Continuing.
Hardware watchpoint 2: a
 
Old value = 10
New value = 11
main ( ) at myprog2.c:10
10          puts( "This is the statement following ++*iPtr." );

Because iPtr points to a, the expression ++*iPtr modifies the value of a. As a result, the debugger stops the program after that operation, and displays the next statement about to be executed.

To continue this example, we can set a "read watchpoint" on the variable b. Watchpoints are included in the list of breakpoints displayed by the command info breakpoints (or info b for short):

(gdb) rwatch b
Hardware read watchpoint 3: b
(gdb) info b
Num Type           Disp Enb Address    What
1   breakpoint     keep y   0x004010ba in main at myprog2.c:9
        breakpoint already hit 1 time
2   hw watchpoint  keep y              a
        breakpoint already hit 1 time
3   read watchpoint keep y              b
(gdb) c
Continuing.
This is the statement following ++*iPtr.
Hardware read watchpoint 3: b
 
Value = 20
0x004010ce in main ( ) at myprog2.c:12
12          printf( "a = %d;  b = %d.\n", a, b );
(gdb) c
Continuing.
a = 11;  b = 20.
...

When the program leaves a blockthat is, when the flow of program execution passes a closing brace (})the debugger automatically deletes all watchpoints for expressions involving local variables that are no longer in scope.

To conclude this section, let us look at how the debugger behaves when you set a watchpoint for an expression with several variables. GDB stops the program each time it accesses (or modifies, depending on the type of watchpoint) any variable in the expression. For the following session, we restart the program examined in the previous examples. When it stops at the breakpoint in line 9, we set a read watchpoint for the expression a + b:

(gdb) b 9
Breakpoint 1 at 0x4010ba: file myprog2.c, line 9.
 (gdb) r
Starting program: ...
 
Breakpoint 1, main ( ) at myprog2.c:9
9           ++*iPtr;
(gdb) rwatch a+b
Hardware read watchpoint 2: a + b

If we now let the program continue, the debugger stops it at the next statement that reads either of the variables a or b. The next such statement is the printf call in line 12. Because that statement reads both a and b, the debugger stops the program twice, displaying the value of the watch expression a + b each time:

(gdb) c
Continuing.
This is the statement following ++*iPtr.
Hardware read watchpoint 2: a + b
 
Value = 31
0x004010ce in main ( ) at myprog2.c:12
12          printf( "a = %d;  b = %d.\n", a, b );
(gdb) c
Continuing.
Hardware read watchpoint 2: a + b
 
Value = 31
0x004010d5 in main ( ) at myprog2.c:12
12          printf( "a = %d;  b = %d.\n", a, b );
(gdb) c
Continuing.
a = 11;  b = 20.
...

20.4.11. Analyzing Core Files in GDB

A core file, or core dump, is a file containing an image of the memory used by a process. Unix systems generally write a core dump in the working directory when a process terminates abnormally. (On Unix systems, you can read which signals trigger a core dump under man signal.) By passing the name of a core file to GDB on the command line, you can examine the state of the process at the moment it was terminated.

A GDB session to analyze a core file is similar to an ordinary debugging session, except that the program you are debugging has already been stopped at a certain position, and you can't use the run, step, next, or continue commands to make it go again. We'll walk through a sample "postmortem" session to illustrate how to debug the program using the other GDB commands. To begin, suppose the program myprog, located in the current directory, has been compiled with the -g option. The following command runs the program:

$ ./myprog
Segmentation fault (core dumped)

The error message indicates that myprog aborted due to an illegal memory access. The system has generated a core file in the current directory with the name core. To analyze the program's error, we will start GDB, passing it the name of the core file as well as the executable file on the command line. On starting, the debugger immediately displays the address and the function in which the program was terminated:

$ gdb myprog core
GNU gdb 6.1
Copyright 2004 Free Software Foundation, Inc.
...
Core was generated by `./myprog'.
Program terminated with signal 11, Segmentation fault.
 
Reading symbols from /lib/tls/libc.so.6...done.
Loaded symbols for /lib/tls/libc.so.6
Reading symbols from /lib/ld-linux.so.2...done.
Loaded symbols for /lib/ld-linux.so.2
#0  0x4008ff06 in strcpy ( ) from /lib/tls/libc.so.6
(gdb)

The last output line indicates that the error took place in the standard library function strcpy( ). If we assume that strcpy( ) itself is bug-free, then myprog must have made an error in calling it. The command backtrace, abbreviated bt, displays the function calls that have led to the current point in the program flow (for more details on backtraces, see the section "Analyzing the Stack," earlier in this chapter):

(gdb) bt
#0  0x4008ff06 in strcpy ( ) from /lib/tls/libc.so.6
#1  0x080483f3 in main ( ) at myprog.c:13
(gdb)

The output indicates that the strcpy( ) call occurs at line 13 of the source file myprog.c, in the function main( ). Each of the numbered lines in the output of the backtrace command corresponds to a stack frame, which is a data structure created on the stack to hold the data required for a function call. The command frame n (or f n for short), where n is the number of a stack frame displayed in the backtrace, selects the stack frame corresponding to the current function's caller, and displays the source code line containing the function call:

(gdb) f 1
#1  0x080483f3 in main ( ) at myprog.c:13
13          strcpy( name, "Jim" );

Because the function call shows that the second argument to strcpy( ) is a string literal, we can assume that the other argument, name, is an invalid pointer. To verify its value, use the print command:

(gdb) p name
$1 = 0x0
(gdb)

The value of name is zero: myprog crashed by trying to write using a null pointer. To correct this bug, you would have to make sure that name points to a char array of sufficient size to hold the string copied to it.


Previous Page
Next Page