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.

CommandShortEffect
runrstart 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
continuecresume until the next stop
continue 5c 5resume, ignoring the next 4 hits of this breakpoint
nextnone source line, stepping over calls
stepsone source line, stepping into calls with debug info
finishfinrun until the current function returns, print the value
untilulike 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 LOCjresume at a different line in the same function
stepisione machine instruction, into calls
nextinione machine instruction, over calls
next 20n 20repeat 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
CommandShortEffect
record fullrecordstart recording, required for reverse commands
reverse-steprsone source line backward, into calls
reverse-nextrnone source line backward, over calls
reverse-stepi / reverse-nextirsi / rnione instruction backward
reverse-finish—back to just before the current function was called
reverse-continuercbackward 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
SettingWhy
set confirm offno "are you sure" on delete and quit
set pagination offlong output scrolls instead of pausing
set print thread-events offquiet down a heavily threaded program
set range-stepping onfewer 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.