Advanced GDB Usage Techniques

Custom Commands

The following statement is written in ~/.gdbinit to define a custom command lmem. This command requires one parameter, which is a memory address that serves as the head of a linked list. The structure of the linked list is BlockLink_t. The function of this command is to traverse the linked list and print the address of each node in sequence:

  define lmem    if $argc < 1      printf "Usage: cmd start_address\n"    else      # first arg goes in $address      set $block=(BlockLink_t *)$arg0      while $block->pxNextFreeBlock != 0        printf "Free mem: "        p/x $block        p/x *$block        set $block=(BlockLink_t *)$block->pxNextFreeBlock      end    end  end

There is a requirement to pause at the memory allocation function malloc and check the current available memory. First, set a breakpoint on the malloc function using “b malloc”.

However, we do not want to pause every time malloc is called, so we can use the command “command” to define actions that occur when the breakpoint is hit:

(gdb) i bNum     Type           Disp Enb Address     What2       breakpoint     keep y   0x1ffe3400  malloc(gdb) command 2Type commands for breakpoint(s) 2, one per line.End with a line saying just "end".>silent>wdo>continue>end

The breakpoint number for malloc is 2, and using “command 2” defines a set of actions to be executed when this breakpoint is hit: the action is simple, it calls wdo, then continues, meaning it will not stop but will continue executing.

wdo is also a custom command defined in ~/.gdbinit, as follows:

  define wdo    set pagination off    printf "\n\n\n---------\n"    bt    printf "---------\n"    lmem  end

The wdo command calls the previously defined lmem.

When defining trigger actions with commands, the keyword silent can be added at the beginning. silent will not print the common message that indicates stopping at a breakpoint. silent only takes effect at the beginning of the breakpoint command list.

Breakpoint Settings

watch (long)*0x22000000 will trigger a breakpoint when writing the address 0x20000000 with a length of long. For more, see rwatch, awatch.

tbreak args sets a breakpoint that only hits once, equivalent to a temporary breakpoint.

hbreak/thbreak sets a hardware breakpoint.

condition bnum expression sets a condition for a breakpoint to interrupt, similar to break xxx if cond.

ignore bnum count ignores the first count hits for a breakpoint. Similar to continue [ignore-count], this sets how many times to ignore the next hit of the breakpoint.

Memory Inspection

x/nfu addr prints memory information, where n is the number, f is the format (same as printf), and u is the unit (b: byte/1 byte, h: halfword/2 bytes, w: word/4 bytes, g: giant word/8 bytes).

p *array@len prints an array, p/x (short[])0x12345678 forcibly casts an address to an array for printing.

dump memory /tmp/ddr.bin 0x20000000 1024 dumps 1024 bytes of data from memory starting at 0x2000000 to the file /tmp/ddr.bin.

set [var] var_name=value, where var is a keyword. When var_name is a gdb keyword, the var keyword needs to be prefixed. For example, set width=4, where set width is a gdb-related setting, so it needs to be set var width=4.

Source Code Path Mapping

set substitute-path from to maps the source file path when the debugged object is not compiled locally. The reverse operation is unset substitute-path [path].

Leave a Comment