GDB Cheatsheet
Running and Stepping
Use this GDB reference while you build software engineering projects, review code, or refresh the syntax you reach for most.
The Core Loop
Six commands cover almost every session. Every one of them repeats when you press Enter on an empty line, which is how you actually step through code.
| Command | Short | Effect |
|---|---|---|
run | r | start the program from the beginning |
start | — | tbreak main plus run, stops at the first line |
starti | — | stop at the very first instruction, before the loader |
continue | c | resume until the next stop |
continue 5 | c 5 | resume, ignoring the next 4 hits of this breakpoint |
next | n | one source line, stepping over calls |
step | s | one source line, stepping into calls with debug info |
finish | fin | run until the current function returns, print the value |
until | u | like next, but does not go backward in a loop |
advance LOC | — | run to a location, one-shot, ends if the frame returns |
return | — | pop the frame now, without running the rest of it |
return 0 | — | pop it and force the return value |
jump LOC | j | resume at a different line in the same function |
stepi | si | one machine instruction, into calls |
nexti | ni | one machine instruction, over calls |
next 20 | n 20 | repeat 20 times |
kill | — | terminate the inferior, keep the session |
(gdb) start Temporary breakpoint 1, main (argc=1, argv=0x7ffd...) at prog.c:12 12 int total = 0; (gdb) n 13 for (int i = 0; i < n; i++) (gdb) 14 total += row(i); (gdb) s row (i=0) at prog.c:4
step only enters functions that have debug info. Stepping into printf from a
stripped libc just steps over it, which is usually what you wanted. set
step-mode on changes that and stops at the first instruction of such a function.
next Versus until Versus finish
These three are what people mix up.
- next at the closing brace of a loop body jumps back to the loop head, so you
go around again.
- until with no argument is next that refuses to move backward, so at the
bottom of a loop it runs the whole remaining loop and stops after it.
- until LINE runs until that line or until the current frame returns, so it
cannot run away if the loop exits early.
- finish runs to the end of the current function and prints Value returned.
(gdb) until (gdb) until 88 # out of the loop, capped by the frame returning (gdb) advance parse_row # run to a function, even in a different frame (gdb) finish Run till exit from #0 row (i=3) at prog.c:4 0x0000555555555191 in main () at prog.c:14 Value returned is $1 = 9
finish from main or from the outermost frame has nothing to return to, and gdb
says so. advance differs from tbreak plus continue because it also stops if
the current frame returns first.
Changing Control Flow
return and jump both lie to the program. They are for testing an error path
without arranging the failure.
(gdb) return -1 Make row return now? (y or n) y (gdb) jump 92 # skip the block you are standing in Continuing at 0x55555555519c. (gdb) call cleanup() # run a function right now (gdb) p open("/dev/null", 0)
return does not run the rest of the function, so any cleanup it would have done
never happens. jump to a line in another function corrupts the frame and usually
crashes. Both are debugging tools, not fixes.
Reverse Execution
Reverse commands need a target that records history. Native Linux gets that from
record, which is a software record-and-replay of the process. It is x86-only,
slows execution a lot, and cannot replay most syscalls or AVX code, but for a
tight crash it is unbeatable.
(gdb) start (gdb) record (gdb) c Program received signal SIGSEGV, Segmentation fault. (gdb) reverse-step # back one source line (gdb) reverse-next # back one line, over calls (gdb) reverse-finish # back to the caller's call site (gdb) reverse-continue # back to the previous breakpoint or watchpoint (gdb) record stop
| Command | Short | Effect |
|---|---|---|
record full | record | start recording, required for reverse commands |
reverse-step | rs | one source line backward, into calls |
reverse-next | rn | one source line backward, over calls |
reverse-stepi / reverse-nexti | rsi / rni | one instruction backward |
reverse-finish | — | back to just before the current function was called |
reverse-continue | rc | backward to the previous stop |
set exec-direction reverse | — | make plain next and continue go backward |
info record | — | how many instructions are recorded |
record stop | — | discard the log |
The killer combination is watch plus reverse-continue. Once the watchpoint
fires on a corrupted value, running backward takes you straight to the write.
Sitting at the Prompt
(gdb) Ctrl-C # interrupt a running inferior (gdb) interrupt # same thing as a command (gdb) info program # is it running, and where (gdb) info inferiors (gdb) set pagination off # stop the "---Type <return>---" prompt (gdb) Ctrl-D # quit, same as quit
| Setting | Why |
|---|---|
set confirm off | no "are you sure" on delete and quit |
set pagination off | long output scrolls instead of pausing |
set print thread-events off | quiet down a heavily threaded program |
set range-stepping on | fewer round trips when stepping on a remote target |
Ctrl-C at the gdb prompt interrupts the inferior. Ctrl-C while gdb itself is
busy in a slow software watchpoint interrupts gdb instead, which is the escape
hatch when a step never seems to finish.