A source level debugger based on `ptrace` for *NIX systems and developed by the GNU project.

GDB is primarily designed for debugging software during development with source available. However, it can also be used to debug without source code and debug symbols available.

It is available on most platforms and included by default in the tool chains of most Unix like operating systems. There are text interfaces as well as graphical ones such as Eclipse integration, the venerable DDD or KDBG.

You can find the comprehensive documentation here.

Default interfaces

The default interfaces are terminal based.

But you can also use the following GDB commands on the (gdb) prompt to switch the layouts on the fly (use help layout to get more information):

  • layout src (only useful with source and symbols)
  • layout asm
  • layout regs

TUI

There is the default layout src which can be invoked using the -tui command line switch.

gdb -tui

Simple prompt

Default when not using any kind of command line switches.

Simple GDB prompt

layout asm together with layout regs

This is by far the most useful layout for reverse engineering, during which debug symbols are usually unavailable. Behold:

layouts asm and regs combined

Beautiful isn't it? You can see the current values of registers, see the assembly at your current program counter, see where the break point was set and so on. And if you prefer the Intel assembly syntax like I do you issue a:

set disassembly-flavor intel

and it looks like this:

enter image description here

Debugging without debug symbols

Normally GDB will attempt to load the debug symbols from the executable itself or in the search paths it was told about. If it doesn't find any symbols or you are reversing/analyzing a target executable without symbols, you can use the following line:

disp/i $pc

to enable an automatic display for the program counter ($pc). So you see what you are going to execute. Starting with GDB 7 you can also use the following setting to achieve virtually the same: set disassemble-next-line on

If you merely want to see the current instruction use:

x/i $pc

which is short for examine.

If you wanted to make sure you don't get surprised by something running before you get control in GDB, you should use:

info file

which will give you an output similar to (shortened for brevity):

(gdb) info file
Symbols from "/home/username/source/hello".
Local exec file:
        `/home/username/source/hello', file type elf64-x86-64.
        Entry point: 0x400410
        0x0000000000400238 - 0x0000000000400254 is .interp
        0x0000000000400254 - 0x0000000000400274 is .note.ABI-tag
        0x0000000000400274 - 0x0000000000400298 is .note.gnu.build-id
        0x0000000000400298 - 0x00000000004002b4 is .gnu.hash
        0x00000000004002b8 - 0x0000000000400318 is .dynsym
        0x0000000000400318 - 0x0000000000400355 is .dynstr
        0x0000000000400356 - 0x000000000040035e is .gnu.version
        0x0000000000400360 - 0x0000000000400380 is .gnu.version_r
        0x0000000000400380 - 0x0000000000400398 is .rela.dyn
        0x0000000000400398 - 0x00000000004003c8 is .rela.plt
        0x00000000004003c8 - 0x00000000004003e0 is .init
        ...

and you are interested to set breakpoints at the lines for the Entry point: and the one with .init (a runtime function running before the entry point):

(gdb) b *0x400410
Breakpoint 1 at 0x400410
(gdb) b *0x00000000004003c8
Breakpoint 2 at 0x4003c8

Notice how we use the asterisk (*) to specify an address for the break point command.

Refining what assembly we see

(gdb) x/5i $pc
=> 0x400410 <_start>:   xor    %ebp,%ebp
   0x400412 <_start+2>: mov    %rdx,%r9
   0x400415 <_start+5>: pop    %rsi
   0x400416 <_start+6>: mov    %rsp,%rdx
   0x400419 <_start+9>: and    $0xfffffffffffffff0,%rsp

Both examine and display allow us to specify the number of instructions we want to see like this to show 5 instructions:

x/5i $pc

we can also tell it to show starting from before the current program counter:

x/10i $pc-3

last but not least we can change from AT&T syntax to Intel syntax:

set disassembly-flavor intel

Example:

(gdb) x/10i $pc-3
   0x40041a <_start+10>:        and    esp,0xfffffff0
=> 0x40041d <_start+13>:        push   rax
   0x40041e <_start+14>:        push   rsp
   0x40041f <_start+15>:        mov    r8,0x4005a0
   0x400426 <_start+22>:        mov    rcx,0x400510
   0x40042d <_start+29>:        mov    rdi,0x4004f4
   0x400434 <_start+36>:        call   0x400400 <__libc_start_main@plt>
   0x400439 <_start+41>:        hlt    
   0x40043a <_start+42>:        nop
   0x40043b <_start+43>:        nop
history | excerpt history