The following sections explain some advanced gdb(1) topics. For more detailed information about these topics, see the Free Software Foundation Web site. (Web addresses can change, so you might be unable to connect to the Web site mentioned here.)
When you debug a program, you can redirect its input or output. For example, you can use predefined input to reproduce a problem, or you can use redirection when debugging an interactive program such as an editor.
There are two different approaches to input/output (I/O) redirection in gdb: you can use set args, or you can redirect I/O to a different terminal window.
On the command line, you can redirect I/O using set args. For example, the following command will store the output of a program in a text file. When the program is run, the output is redirected to output.txt in the current directory:
(gdb) set args in/out > output.txt
You can also redirect input. In fact, both input and output can be redirected on the same line.
An alternative to set args is the tty command, which sends program I/O to a different terminal window. This is useful when debugging an interactive program such as an editor. To use the tty command, open a second Interix shell window. Then use the tty command to determine the device name for the second window:
$ tty
ttyn01
To redirect output from the program in the gdb session to the second terminal window, type:
(gdb) tty /dev/ttyn01
The gdb utility can detect any signal intended for your program. Usually, any non-error signal (typically, any signal other than SIGINT or SIGSEGV) is passed through to the program.
To get a list of the kinds of signals on the system and how gdb handles them, type the command:
info signals
The handle command modifies how gdb deals with signals. Its basic structure is described in the following section.
The following table describes typical keywords:
Keyword | Description |
---|---|
stop | nostop | Stops (or does not stop) execution on receipt of the signal. |
print | noprint | Prints (or does not print) a message if this signal occurs. |
pass | nopass | Passes (or does not pass) the signal to the program. |
It is important to use the symbolic form because, internally, gdb maps signals to different numbers. If you specify the numeric form (signal 9, for example), gdb will intercept its own signal 9, not the system’s signal 9.
When you want to debug an existing process, use the ps command to find its process identification (ID) number. Then, instead of the file name, specify the process ID on the command line. The gdb utility first looks for a file by that name, reports that it does not exist, and then, if possible, attaches to the process. If successful, it stops the process.
Next, load the symbol information for the program associated with the process by using the file command. You might also need to specify the location of the source files with the directory command. If the source files are in multiple directories, use multiple arguments with the directory command.
The default source path for gdb is $cdir:$cwd, which is the value of the compilation directory and the current working directory. The gcc(1) compiler and some other compilers store the entire path name of the source file in the object file. The value of $cdir is taken from this path name. A compilation directory might not be specified.
The current working directory is the actual current working directory throughout the session, not just the directory where the gdb session was started. Each time you add a directory using the directory command, it is added to the beginning of the source path.
The $cdir macro is never set because the Interix port of gcc does not include all of the path information in the object files.
The gdb utility provides command-line editing with either a vi(1) style or an emacs style. The default is an emacs style. The gdb utility also has a command-history mechanism.
By default, command-line editing is on. You can turn it off with the command set editing off. Switching command-line editing to vi style requires that you have the file .inputrc in your home directory. This file should contain the line:
set editing-mode vi
The .inputrc file is read by the functions of the read-line library that are compiled into gdb. All GNU software that uses the read-line library reads your $HOME/.inputrc file. Following are the variable settings in the .inputrc file:
You can also use the .inputrc file for setting new key bindings for line-editing commands. A description of this, however, is beyond the scope of this topic.
The following commands work like their source code counterparts, but they act on the machine language instructions generated in the object code.
Command | Description |
---|---|
nexti (ni) | Displays the next machine language instruction without descending into a called routine. |
stepi (si) | Displays the next machine language instruction, stepping into called routines. |
disassemble [start[,stop]] | Disassembles a chunk of memory, usually a function. The start and stop addresses represent the range of memory to be disassembled. If you provide only a start address, the command disassembles the function surrounding the address. With no arguments, the command disassembles the function surrounding the program counter of the current stack frame. |
In the Interix version of gdb, you can use the set assembly-language command to control which assembly language is generated, either i386 (the default) or i8086. You can display the active assembly language by typing the command show assembly-language.
Most functions in the application can be called from the gdb command line. This can be useful in debugging: if you need to know what the exp function returns, you can type:
(gdb) print exp(3.0)...
Often if the application has a structured dump of some data structure, it can be called from the gdb command line. For example, the following would call the walk_tree() function in the application:
(gdb) print walk_tree(local)
Commands can be associated with a breakpoint. If, for example, you want to display the variable i every time you reached line 136, you would use:
b 136
<print breakpoint #>
comm <#>
print i
end
Breakpoints can also be conditional. To stop if i exceeds 200, use:
cond <#> i>200