GDB Cheatsheet

lldb Equivalents

Use this GDB reference while you build software engineering projects, review code, or refresh the syntax you reach for most.

Why You Need This

On macOS, lldb is the system debugger and gdb is not installed. On Linux, lldb ships with LLVM and is what Clang, Swift, and Rust tooling assume. The two share almost no command spelling, so a gdb reflex produces is not a known command.

lldb commands are noun verb with heavy aliasing. breakpoint set --name main is the real command, br s -n main is the same thing, and b main is a separate regex-based shorthand. Every alias below was checked against a running lldb.

lldb ./prog                # load
lldb -- ./prog -v in.csv   # everything after -- is the program's argv
lldb -p 1234               # attach by pid
lldb -n prog               # attach by process name
lldb -c core.4711 ./prog   # load a core
lldb -b -o "run" -o "bt" ./prog     # batch, like gdb --batch -ex
gdb flaglldb flag
--args prog a b-- prog a b, or --file prog then settings set target.run-args
-ex CMD-o CMD (--one-line), repeatable and ordered
-x FILE-s FILE (--source)
--batch-b (--batch)
-nx-x (--no-lldbinit)
-p PID-p PID
-c CORE-c CORE
~/.gdbinit~/.lldbinit, plus ./.lldbinit if enabled in settings

Breakpoints and Watchpoints

gdblldb
break mainbreakpoint set --name main · br s -n main · b main
break file.c:42breakpoint set --file file.c --line 42 · br s -f file.c -l 42
break *0x1000breakpoint set --address 0x1000 · br s -a 0x1000
break Ns::fbr s -M f (method) or br s -n Ns::f
break f if x == 0br s -n f -c 'x == 0'
condition 1 x > 2breakpoint modify -c 'x > 2' 1
ignore 1 10breakpoint modify -i 10 1
tbreak fbr s -o true -n f (--one-shot)
rbreak ^http_breakpoint set --func-regex ^http_ · br s -r ^http_
catch throwbreakpoint set -E c++ (--language-exception)
commands 1 ... endbreakpoint command add 1
info breakpointsbreakpoint list · br l
delete 1breakpoint delete 1 · br del 1
disable 1 / enable 1breakpoint disable 1 / breakpoint enable 1
watch totalwatchpoint set variable total · wa s v total
watch -l *pwatchpoint set expression -- p
rwatch vwatchpoint set variable -w read v
awatch vwatchpoint set variable -w read_write v
info watchpointswatchpoint list
catch syscallno equivalent, lldb has no syscall catchpoint

Running, Stepping, Frames

gdblldb
runprocess launch · run · r
startprocess launch --stop-at-entry · pro la -s
continue / cprocess continue · continue · c
next / nthread step-over · next · n
step / sthread step-in · step · s
finish / finthread step-out · finish · fin
stepi / sithread step-inst · si
nexti / nithread step-inst-over · ni
until 88thread until 88
return 0thread return 0
jump 92thread jump --line 92
killprocess kill · kill
detachprocess detach
attach 1234process attach --pid 1234
btthread backtrace · bt
bt 5bt 5
bt fullno single equivalent, bt then frame variable per frame
thread apply all btthread backtrace all · bt all
frame 2 / f 2frame select 2 · f 2
up / downup / down
info frameframe info
info localsframe variable --no-args · v -a (bare v shows both)
info argsframe variable --no-locals · v -l
info threadsthread list
thread 2thread select 2 · t 2
set scheduler-locking onno equivalent, lldb has no scheduler locking

Data, Memory, and Symbols

gdblldb
print x / p xexpression x · p x (print is dwim-print)
p/x xp/x x · expression -f hex -- x
p *ap@5parray 5 ap, the @ syntax does not exist
p arr[2]@3parray 3 &arr[2]
ptype struct configtype lookup config · image lookup -t config
whatis xexpression -T -- x, or read the type in p output
set var x = 5expression x = 5 · expr x = 5
call f(1)expression f(1) · p f(1)
display xtarget stop-hook add -o "p x"
set print pretty onon by default, tune with type summary add
x/16xb bufx/16xb buf · memory read -f x -s 1 -c 16 buf
x/5xw &arrx/5xw &arr, and x/5xw arr is an error on an array, see below
x/5i $pcx/5i $pc · disassemble -s $pc -c 5
find &a, +100, 0xdeadmemory find -e 0xdead -- &a &a+100
info registers / i rregister read · re r
info all-registersregister read --all
p $rspp $rsp, register read sp also works
set var $rax = 0register write rax 0
disassembledisassemble --frame · di -f
disassemble /s fdisassemble -m -n f (--mixed)
disassemble /r fdisassemble -b -n f (--bytes)
info symbol 0x1000image lookup --address 0x1000 · im loo -a 0x1000
info line fimage lookup -F f or source info -f file.c
info functions ^http_image lookup -r -n ^http_
info sharedlibraryimage list · target modules list
info proc mappingsmemory region ADDR, one region at a time
gcore out.coreprocess save-core out.core
set sysroot /tmp/rootplatform select -S /tmp/root remote-linux, plus target.exec-search-paths
set solib-search-path Asettings set target.exec-search-paths A
set substitute-path A Bsettings set target.source-map A B

Settings, Scripting, and the UI

gdblldb
set confirm offsettings set auto-confirm true
set pagination offno equivalent setting, lldb does not page command output
set disassembly-flavor intelsettings set target.x86-disassembly-flavor intel
set follow-fork-mode childsettings set target.process.follow-fork-mode child
set stop-on-solib-events 1settings set target.process.stop-on-sharedlibrary-events true
set print elements 0settings set target.max-string-summary-length 4096
show CONFIGsettings show CONFIG
define NAME ... endcommand alias NAME ... for one command
a multi-line definecommand script add -f mod.fn NAME
python print(1)script print(1)
python-interactivescript with no argument
source f.pycommand script import f.py
gdb.execute("bt")lldb.debugger.HandleCommand("bt")
gdb.parse_and_eval("x")frame.EvaluateExpression("x") in the SB API
shell lsplatform shell ls
tui enablegui
apropos WORDapropos WORD
help breakhelp breakpoint set
quit / qquit · q

Differences That Bite

x needs an address, not an array. In lldb an array expression is not convertible to an address, so take it explicitly.

(lldb) x/5xw arr
error: invalid start address expression.
error: address expression "arr" resulted in a value whose type can't be
converted to an address: int[5]
(lldb) x/5xw &arr
0x100008000: 0x00000003 0x00000001 0x00000004 0x00000001

-b stops at the first error. In batch mode, one failing -o command aborts every command after it, so an out-of-scope variable silently truncates your script. gdb --batch keeps going.

No @ artificial arrays. p *ap@5 is a syntax error. Use parray 5 ap.

No syscall catchpoints and no scheduler locking. apropos syscall and apropos scheduler both come back empty. There is no substitute, and for single-thread stepping the closest thing is thread step-over with the other threads left running.

print is not expression. In current lldb, print and p are dwim-print, which tries a frame-variable lookup before evaluating an expression. It is faster and usually identical, but expression is what takes the full option set.

gdb on macOS

gdb still builds on macOS through Homebrew, but it cannot control a process without being granted debugging rights, so it needs a signed certificate with the com.apple.security.cs.debugger entitlement, or sudo. Symptoms of an unsigned gdb are:

Unable to find Mach task port for process-id 1234:
  (os/kern) failure (0x5). (please check gdb is codesigned)

The steps are creating a self-signed code-signing certificate in Keychain Access, trusting it for code signing, then codesign -s <cert> --entitlements gdb.xml $(which gdb) with an entitlements plist granting com.apple.security.cs.debugger, and a reboot or a taskgated restart. gdb also lags behind Apple's arm64 platform support, so on Apple silicon lldb is the practical choice and this table is the translation layer. On Linux both work fully, and the choice is only preference.