GDB Cheatsheet
Memory and Registers
Use this GDB reference while you build software engineering projects, review code, or refresh the syntax you reach for most.
x, the Examine Command
x/NFU addr reads raw memory and formats it, ignoring the declared type. The three
parts are a repeat count, a format letter, and a unit size.
x/NFU addr N repeat count, decimal, default 1, negative reads backward F format letter U unit size
| Unit | Size |
|---|---|
b | byte, 1 |
h | halfword, 2 |
w | word, 4, the initial default |
g | giant word, 8 |
| Format | Reads as |
|---|---|
x | hex, the initial default |
d / u | signed / unsigned decimal |
o / t | octal / binary |
c | character |
f | floating point |
a | address plus nearest symbol |
s | null-terminated string, unit defaults to b |
i | machine instruction, unit ignored |
m | memory tags, on architectures that have them |
(gdb) x/4xw $sp # 4 words of the stack in hex 0x7fffffffe1c0: 0x00000001 0x00000000 0xffffe2a8 0x00007fff (gdb) x/16xb buf # 16 raw bytes (gdb) x/s name # as a C string 0x555555556004: "api" (gdb) x/8xg $rsp # 8 pointer-sized words (gdb) x/5i $pc # next 5 instructions, => marks the pc (gdb) x/40a $sp # stack words resolved against symbols (gdb) x/-3uh 0x54320 # three halfwords BEFORE that address (gdb) x/7 # continue where the last x left off
Order does not matter between the format and the unit, so x/4xw and x/4wx are
identical, but the count must come first. x remembers the format and unit you
last used, and remembers the next address, so a bare x/7 keeps scanning. Enter on
an empty line repeats with the same count.
(gdb) p $_ # last address x examined (gdb) p $__ # the contents at that address (gdb) x/4xw &arr # take the address, arr is not a pointer
Writing Memory and Searching It
(gdb) set {int}0x555555558010 = 7 # write 4 bytes at an address (gdb) set var *(char *) buf = 'X' (gdb) set var buf[0] = 0 (gdb) find &main, +0x10000, 0x554889e5 # search for a byte pattern (gdb) find /w &data, +4096, 0xdeadbeef # search word-sized (gdb) find /b &buf, +256, 'A', 'B', 'C' (gdb) find &start, &end, "needle"
| Command | Effect |
|---|---|
set {TYPE}ADDR = val | write, using TYPE for the width |
find start, +len, pattern | search a range, /b /h /w /g set the width |
find /1 start, end, pat | stop after the first match |
dump binary memory f.bin S E | write memory from S to E into a file |
restore f.bin binary ADDR | read a raw file back in at ADDR |
compare-sections | check the loaded image against the executable |
dump binary memory is how you pull a corrupted buffer out for inspection with
xxd or a parser, without scrolling thousands of x lines.
Registers
(gdb) info registers # i r, the general-purpose set rax 0x2a 42 rbx 0x0 0 rsp 0x7fffffffe1c0 0x7fffffffe1c0 rip 0x555555555149 0x555555555149 <main+16> eflags 0x246 [ PF ZF IF ] (gdb) i r rax rdi rsi # only these (gdb) i r $eflags (gdb) info all-registers # plus SSE, AVX, and the FPU (gdb) info registers vector # one register group (gdb) p/x $rip (gdb) p $pc # architecture-neutral aliases (gdb) set var $rax = 0
| Command | Short | Shows |
|---|---|---|
info registers | i r | integer and status registers |
info registers rax rbx | i r rax rbx | named registers only |
info all-registers | — | every register, including vector and float |
info registers general | — | one register group, see maint print reggroups |
p $pc p $sp p $fp | — | portable names for pc, stack and frame pointer |
p $rax | — | the x86-64 register by its own name |
Register names in expressions always take a $. Without it, p rax looks for a
program symbol called rax and fails. In an older frame the registers shown are
the saved values gdb unwound, so writing to them in frame 3 is not meaningful.
Disassembling
(gdb) disassemble # the current function (gdb) disassemble main (gdb) disassemble /s main # interleaved with source, in source order (gdb) disassemble /r main # plus raw bytes (gdb) disassemble /b main # raw bytes, one per instruction line (gdb) disassemble 0x401136, 0x401180 (gdb) disassemble 0x401136, +32 (gdb) x/20i $pc-8
| Command | Effect |
|---|---|
disassemble | the function containing the pc, => marks it |
disassemble /s | interleave source lines, in program order |
disassemble /m | interleave source, in source-line order, deprecated |
disassemble /r | show the raw instruction bytes too |
set disassembly-flavor intel | Intel syntax instead of AT&T |
set disassemble-next-line on | disassemble automatically at every stop |
set disassembler-options no-aliases | pass options through to the disassembler |
info line *0x401136 | which source line an address belongs to |
Prefer /s over /m. /m walks source lines in order and cannot represent
reordered or inlined code, which is exactly the situation where you are reading
disassembly.
Addresses, Symbols, and the Memory Map
(gdb) info symbol 0x555555555149 main + 16 in section .text of /home/me/prog (gdb) info address total Symbol "total" is a variable at frame base reg $rbp offset 16+-20. (gdb) info line prog.c:14 (gdb) p/a $pc
(gdb) info proc mappings process 4711 Start Addr End Addr Size Offset Perms objfile 0x555555554000 0x555555555000 0x1000 0x0 r--p /home/me/prog 0x7ffff7d8b000 0x7ffff7db3000 0x28000 0x0 r--p /lib/.../libc.so.6 0x7ffffffde000 0x7ffffffff000 0x21000 0x0 rw-p [stack]
| Command | Shows |
|---|---|
info symbol ADDR | which symbol and section an address falls in |
info address SYM | where a symbol lives, register or memory or frame offset |
info proc mappings | the full /proc/pid/maps view, Linux only |
info proc cmdline / cwd / exe | how the process was started |
info proc status / stat | the raw /proc status fields |
info files | sections of every loaded object, with load addresses |
info sharedlibrary | which libraries are mapped and whether symbols are read |
maint info sections | every section, including gdb's internal view |
info proc mappings is the fastest way to decide what a wild pointer was. If the
address falls in an r--p region it was a write to read-only data, and if it falls
in no region at all it was never mapped. info symbol on the crash address usually
names the function or the global that got overrun.