Gem #119 : GDB Scripting— Part 1
by Jean-Charles Delay —AdaCore
Let's get started...
The GDB configuration file is located in the user's home directory:
${HOME}/.gdbinit.
When GDB starts, it sources this file -- if it exists -- meaning that it evaluates all the commands in the file, which can be any of the available CLI commands. At a basic level, this file can be used for simple configuration commands, such as selecting the default assembler format desired or changing the default input/output radix display style.
But GDB offers more: it can also read a macro-coding language that allows more powerful customizations.
This language follows the following format:
define _command_ _code_ end document _command_ _help text_ end
Commands defined like this are known as user commands. You can use and combine any standard GDB CLI commands in your user-defined macros.
The document section is important, since it is used by GDB to produce the output for the help command when associated with user-defined commands.
The GDB language also offers you a set of flow-control instructions and allows parameters. However, parameter manipulation is limited, because GDB only offers the following variables:
$argc $arg0 $arg1 $arg2 ...
However, note that GDB does not provide an array such as $argv.
Flow-control Instructions
GDB provides the "survival kit" for any language, meaning:
- The set statement
- The if control structure for conditions
- The while control structure for loops
The Set Statement
You can assign the result of an expression to an environment variable with set, for example:
set $VAR = 0 set $byte = *(unsigned char *)$arg0
The If Statement
if _expression_ _statements_ else _statements_ end
The While Statement
while _expression_ _statements_ end
Controlled Output
During the execution of a command file or a user-defined command, normal GDB output is suppressed; the only output that appears is what is explicitly printed by the commands in the definition.
GDB provides three commands for generating any desired output:
echo _text_
This command prints _text_ including any nonprintable character escaped in a C-style string. No newline is printed unless you specify one using the ` ' character. You can also use escape sequences to output colors for a color terminal. For example, `\033[01;31' prints the following characters in red, whereas `\033[0m' resets the colored output to default.
output _expression_
This prints the value of _expression_ and nothing but that value (no newline, no `$nn = ').
printf _string_, _expressions_...
This prints the values of the _expressions_ under control of the format string _string_. The _expressions_ may be either numbers or pointers.
For example, you can print two values in hex like this:
printf "foo, bar-foo = 0x%x, 0x%x ", foo, bar-foo
Invoking the Shell
You can invoke a shell through the GDB command shell. If it exists, GDB uses the $SHELL environment variable to determine which shell to run. Otherwise it uses the default shell (`/bin/sh' on Unix systems, `COMMAND.COM' on MS-DOS, etc.).
Invoking make
Let's say that you compile your project using a Makefile and the make program. You may then want to use the GDB shell command to run make. GDB generally provides you with a make command of its own that executes the make program. For GNAT Pro Ada users though, the build program is gprbuild, which doesn't natively exist in GDB. However, you can define a command that will invoke it, for example:
define gprbuild if $argc == 0 shell gprbuild end if $argc == 1 shell gprbuild $arg0 end if $argc > 1 help gprbuild end end document gprbuild Run the gprbuild program, optionally specifying the project name as parameter. Usage: gprbuild [project_name] end
Radix Display Style
GDB allows you to change the default radix display style -- for both input and output -- allowing the following formats: octal, decimal, and hexadecimal.
You can always enter numbers in octal, decimal, or hexadecimal in GDB by the usual conventions: octal numbers begin with `0', decimal numbers end with `.', and hexadecimal numbers begin with `0x'.
However, numbers that begin with none of these are, by default, entered in base 10.
The radix commands are the following:
set input-radix _base_ set output-radix _base_
Caution: base must itself be specified either unambiguously or using the current default radix.
Therefore, you can select the hexadecimal style by default through the following commands:
set input-radix 0x10 set output-radix 0x10
Prompt Look
Changing the prompt look is also possible, and similar to changing your shell prompt. The following example makes your gdb prompt `gdb$' display in red:
set prompt \033[01;31mgdb$ \033[0m
Preventing GDB from Pausing during Long Output
You might have already experienced that when GDB needs to print more lines than your terminal height can display, it pauses each time the console is full. To prevent that and make GDB display all information at once, use the following settings:
set height 0 set width 0
Changing the Assembler Code Format
GDB supports different kinds of instruction set formats when disassembling a program via the disassemble or x/i commands.
You can set GDB to use either intel or att format. However, this command is only defined for the Intel x86 family:
set disassembly-flavor intel set disassembly-flavor att
The default instruction set is att (the AT&T flavor used by default by Unix assemblers for x86-based targets).
Optional Messages
By default, GDB is cautious, and asks what sometimes seem to be a lot of questions to confirm certain commands. If you are willing to unflinchingly face the consequences of your own commands, you can disable this "feature":
set confirm off
Going Further
For a full list of GDB capabilities, see the GDB manual.
In a future Gem we will provide examples of GDB's more sophisticated scripting capabilities.