Notes on GDB
This is a living document containing my notes on GDB usage
gdbinit
The script ~/.gdbinit
will always be run when starting gdb
. A good default is:
set width 0
set height 0
set print pretty on
set disassembly-flavor intel
set confirm off
These will
- Disable paging
- Turn on pretty printing
- Set the assembly syntax to Intel
- Remove the confirmation message when exiting
Debugging Levels
If the code has a lot of macros, consider using debug info level of -g3
. This allows gdb
to expand macros when debugging
Passing Arguments
To pass arguments to a program launched with gdb
, use the --args
switch with the program name as the first argument:
gdb --args a.out --switch1 --switch2=somesetting
Then in gdb you can see arguments anytime:
(gdb) show args
" --switch1 --switch2=somesetting"
Conditonal Breakpoints
Breakpoints can have conditions. If I want to break some_function(int n)
, but only when n == 3
:
(gdb) break some_function if n == 3
Scripting
Consider the following file gdbscript
:
# gdbscript
b 12
b other.c:45
r
When run with gdb -x gdbscript a.out
, this will set breakpoints and start the program.
Caveats
Everything in gdb scripting is global. Be careful with function and variable definitions
Commands
Commands will be run on every breakpoint. With the following snippet of C code:
int n = 0;
# starts at line 32
for (int i = 0; i < 10; i++) {
++n;
}
The following gdbscript will print every other value of i
during iteration:
# gdbscript
set $x = 0
b 32
commands
set $x = $x + 1
if $x % 2 == 0
printf "n: %d\n", n
end
c
end
run
Macros
Macros can be defined in gdbscript to be used during a debugging session. Here’s an interesting macro that prints the values of the x86 eflags register (Taken from adacore)
define eflags
printf " OF <%d> DF <%d> IF <%d> TF <%d>",\
(($eflags >> 0xB) & 1), (($eflags >> 0xA) & 1), \
(($eflags >> 9) & 1), (($eflags >> 8) & 1)
printf " SF <%d> ZF <%d> AF <%d> PF <%d> CF <%d>
",\
(($eflags >> 7) & 1), (($eflags >> 6) & 1),\
(($eflags >> 4) & 1), (($eflags >> 2) & 1), ($eflags & 1)
printf " ID <%d> VIP <%d> VIF <%d> AC <%d>",\
(($eflags >> 0x15) & 1), (($eflags >> 0x14) & 1), \
(($eflags >> 0x13) & 1), (($eflags >> 0x12) & 1)
printf " VM <%d> RF <%d> NT <%d> IOPL <%d>
",\
(($eflags >> 0x11) & 1), (($eflags >> 0x10) & 1),\
(($eflags >> 0xE) & 1), (($eflags >> 0xC) & 3)
end
This macro can then be run at any time during a debugging session
(gdb) eflags
OF <0> DF <0> IF <1> TF <0> SF <1> ZF <0> AF <0> PF <0> CF <0>
ID <1> VIP <0> VIF <0> AC <0> VM <0> RF <0> NT <0> IOPL <0>
Hook-stop
The hook stop macro is called every time the program hits a breakpoint. This can be combined with user-defined macros. In this example, we will call the above eflags
macro every time we hit a breakpoint:
define hook-stop
eflags
end