20.4. Using GDB CommandsUpon 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 CompletionThe 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 CommandsGDB 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 InformationTo 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 debuggedThe 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 debuggerLike 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 DebuggerThe following GDB commands allow you to control programs running in the debugger:
20.4.5. Displaying Source CodeYou 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:
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:
20.4.6. Working with BreakpointsOn 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 breakpointsSet 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:
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 breakpointsThe 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.
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 breakpointsNormally, 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.
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 BreakWhen 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.
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 StackThe 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 traceWhen 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 frameMost 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 variablesThe info command has three subcommands that are useful in displaying the contents of the current stack frame:
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 DataUsually 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 expressionsThe 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 formatsThe 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:
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:
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 blocksThe 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:
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 VariablesGDB 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:
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 GDBA 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. |