Below is a table of GDB commands with their LLDB counterparts. The built in GDB-compatibility aliases in LLDB are also listed. The full lldb command names are often long, but any unique short form can be used. Instead of “breakpoint set”, “br se” is also acceptable.
(gdb) run (gdb) r
(lldb) process launch (lldb) run (lldb) r
<args>(gdb) run <args> (gdb) r <args>
(lldb) process launch -- <args> (lldb) run <args> (lldb) r <args>
a.out with arguments 1 2 3 by passing the args to the debugger% gdb --args a.out 1 2 3 (gdb) run ... (gdb) run ...
% lldb -- a.out 1 2 3 (lldb) run ... (lldb) run ...
1 2 3 by setting the args in the debugger(gdb) set args 1 2 3 (gdb) run ... (gdb) run ...
(lldb) settings set target.run-args 1 2 3 (lldb) run ... (lldb) run ...
(lldb) process launch --tty -- <args> (lldb) pro la -t -- <args>
<args> in existing terminal /dev/ttys006(lldb) process launch --tty=/dev/ttys006 -- <args> (lldb) pro la -t/dev/ttys006 -- <args>
(gdb) set env DEBUG 1
(lldb) settings set target.env-vars DEBUG=1 (lldb) set se target.env-vars DEBUG=1 (lldb) env DEBUG=1
(gdb) unset env DEBUG
(lldb) settings remove target.env-vars DEBUG (lldb) set rem target.env-vars DEBUG
(gdb) show args Argument list to give program being debugged when it is started is "1 2 3".
(lldb) settings show target.run-args target.run-args (array of strings) = [0]: "1" [1]: "2" [2]: "3"
(lldb) process launch -E DEBUG=1
(gdb) attach 123
(lldb) process attach --pid 123 (lldb) attach -p 123
a.out(gdb) attach a.out
(lldb) process attach --name a.out (lldb) pro at -n a.out
a.out to launch and attach(gdb) attach -waitfor a.out
(lldb) process attach --name a.out --waitfor (lldb) pro at -n a.out -w
eorgadd, port 8000(gdb) target remote eorgadd:8000
(lldb) gdb-remote eorgadd:8000
8000(gdb) target remote localhost:8000
(lldb) gdb-remote 8000
eorgadd(gdb) kdp-reattach eorgadd
(lldb) kdp-remote eorgadd
(gdb) step (gdb) s
(lldb) thread step-in (lldb) step (lldb) s
(gdb) skip abc Function abc will be skipped when stepping.
(lldb) settings show target.process.thread.step-avoid-regexp target.process.thread.step-avoid-regexp (regex) = ^std:: (lldb) settings set target.process.thread.step-avoid-regexp ^std::|^abc
You can ignore a function once using:
(lldb) thread step-in -r ^abc
Or you can do the opposite, only step into functions matching a certain name:
# Step in if abc is a substring of the function name. (lldb) sif abc # Which is equivalent to: (lldb) thread step-in -t abc
thread step-in has more options which cover some of skip's other features. See help thread step-in for details.
(gdb) next (gdb) n
(lldb) thread step-over (lldb) next (lldb) n
(gdb) stepi (gdb) si
(lldb) thread step-inst (lldb) si
(gdb) nexti (gdb) ni
(lldb) thread step-inst-over (lldb) ni
(gdb) finish
(lldb) thread step-out (lldb) finish
(gdb) return <RETURN EXPRESSION>
(lldb) thread return <RETURN EXPRESSION>
(lldb) target stop-hook add Enter your stop hook command(s). Type 'DONE' to end. > bt > disassemble --pc > DONE Stop hook #1 added.
(gdb) until 12
(lldb) thread until 12
(gdb) frame
(lldb) frame select (lldb) f (lldb) process status
(gdb) break main
(lldb) breakpoint set --name main (lldb) br s -n main (lldb) b main
test.c at line 12(gdb) break test.c:12
(lldb) breakpoint set --file test.c --line 12 (lldb) br s -f test.c -l 12 (lldb) b test.c:12
main(gdb) break main (Hope that there are no C functions named main)
(lldb) breakpoint set --method main (lldb) br s -M main
-[NSString stringWithFormat:](gdb) break -[NSString stringWithFormat:]
(lldb) breakpoint set --name "-[NSString stringWithFormat:]" (lldb) b -[NSString stringWithFormat:]
count(gdb) break count (Hope that there are no C or C++ functions named count)
(lldb) breakpoint set --selector count (lldb) br s -S count
(gdb) rbreak regular-expression
(lldb) breakpoint set --func-regex regular-expression (lldb) br s -r regular-expression
#include .c/.cpp/.m files(gdb) b foo.c:12
(lldb) settings set target.inline-breakpoint-strategy always (lldb) br s -f foo.c -l 12
(gdb) shell grep -e -n pattern source-file (gdb) break source-file:CopyLineNumbers
(lldb) breakpoint set --source-pattern regular-expression --file SourceFile (lldb) br s -p regular-expression -f file
(gdb) break foo if strcmp(y,"hello") == 0
(lldb) breakpoint set --name foo --condition '(int)strcmp(y,"hello") == 0' (lldb) br s -n foo -c '(int)strcmp(y,"hello") == 0'
(gdb) info break
(lldb) breakpoint list (lldb) br l
(gdb) delete 1
(lldb) breakpoint delete 1 (lldb) br del 1
(gdb) disable 1
(lldb) breakpoint disable 1 (lldb) br dis 1
(gdb) enable 1
(lldb) breakpoint enable 1 (lldb) br en 1
(gdb) watch global_var
(lldb) watchpoint set variable global_var (lldb) wa s v global_var
The size of the region to watch for defaults to the pointer size if no ‘-x byte_size’ is specified. This command takes raw input, evaluated as an expression returning an unsigned integer pointing to the start of the region, after the ‘--’ option terminator.
(gdb) watch -location g_char_ptr
(lldb) watchpoint set expression -- my_ptr (lldb) wa s e -- my_ptr
(lldb) watch set var global (lldb) watchpoint modify -c '(global==5)' (lldb) c ... (lldb) bt * thread #1: tid = 0x1c03, 0x0000000100000ef5 a.out`modify + 21 at main.cpp:16, stop reason = watchpoint 1 frame #0: 0x0000000100000ef5 a.out`modify + 21 at main.cpp:16 frame #1: 0x0000000100000eac a.out`main + 108 at main.cpp:25 frame #2: 0x00007fff8ac9c7e1 libdyld.dylib`start + 1 (lldb) frame var global (int32_t) global = 5
(gdb) info break
(lldb) watchpoint list (lldb) watch l
(gdb) delete 1
(lldb) watchpoint delete 1 (lldb) watch del 1
(gdb) info args (gdb) info locals
(lldb) frame variable (lldb) fr v
(gdb) info locals
(lldb) frame variable --no-args (lldb) fr v -a
bar(gdb) p bar
(lldb) frame variable bar (lldb) fr v bar (lldb) p bar
bar formatted as hex(gdb) p/x bar
(lldb) frame variable --format x bar (lldb) fr v -f x bar
baz(gdb) p baz
(lldb) target variable baz (lldb) ta v baz
(lldb) target variable (lldb) ta v
argc and argv every time you stop(gdb) display argc (gdb) display argv
(lldb) target stop-hook add --one-liner "frame variable argc argv" (lldb) ta st a -o "fr v argc argv" (lldb) display argc (lldb) display argv
argc and argv only when you stop in the function named main(lldb) target stop-hook add --name main --one-liner "frame variable argc argv" (lldb) ta st a -n main -o "fr v argc argv"
*this only when you stop in c class named MyClass(lldb) target stop-hook add --classname MyClass --one-liner "frame variable *this" (lldb) ta st a -c MyClass -o "fr v *this"
int *ptr(gdb) p *ptr@10
(lldb) parray 10 ptr
(gdb) print (int) printf ("Print nine: %d.", 4 + 5)
or if you don't want to see void returns:
(gdb) call (int) printf ("Print nine: %d.", 4 + 5)
(lldb) expr (int) printf ("Print nine: %d.", 4 + 5)
or using the print alias:
(lldb) print (int) printf ("Print nine: %d.", 4 + 5)
(gdb) set $foo = 5 (gdb) set variable $foo = 5
or using the print command
(gdb) print $foo = 5
or using the call command
(gdb) call $foo = 5
and if you want to specify the type of the variable:
(gdb) set $foo = (unsigned int) 5
In lldb you evaluate a variable declaration expression as you would write it in C:
(lldb) expr unsigned int $foo = 5
(gdb) po [SomeClass returnAnObject]
(lldb) expr -o -- [SomeClass returnAnObject]
or using the po alias:
(lldb) po [SomeClass returnAnObject]
(gdb) set print object 1 (gdb) p someCPPObjectPtrOrReference (Only works for C++ objects)
LLDB does this automatically if determining the dynamic type does not require running the target (in C++, running the target is never needed). This default is controlled by the target.prefer-dynamic-value setting. If that is disabled, it can be re-enabled on a per-command basis:
(lldb) settings set target.prefer-dynamic-value no-dynamic-values (lldb) frame variable -d no-run-target someCPPObjectPtrOrReference (lldb) expr -d no-run-target -- someCPPObjectPtr
Note that printing of the dynamic type of references is not possible with the expr command. The workaround is to take the address of the reference and instruct lldb to print the children of the resulting pointer.
(lldb) expr -P1 -d no-run-target -- &someCPPObjectReference
(gdb) set unwindonsignal 0 (gdb) p function_with_a_breakpoint()
(lldb) expr -i 0 -- function_with_a_breakpoint()
(gdb) set unwindonsignal 0 (gdb) p function_which_crashes()
(lldb) expr -u 0 -- function_which_crashes()
(gdb) info threads
(lldb) thread list
1 as the default thread for subsequent commands(gdb) thread 1
(lldb) thread select 1 (lldb) t 1
(gdb) bt
(lldb) thread backtrace (lldb) bt
(gdb) thread apply all bt
(lldb) thread backtrace all (lldb) bt all
(gdb) bt 5
(lldb) thread backtrace -c 5 (lldb) bt 5
(gdb) frame 12
(lldb) frame select 12 (lldb) fr s 12 (lldb) f 12
(lldb) frame info
(gdb) up
(lldb) up (lldb) frame select --relative=1
(gdb) down
(lldb) down (lldb) frame select --relative=-1 (lldb) fr s -r-1
(gdb) up 2 (gdb) down 3
(lldb) frame select --relative 2 (lldb) fr s -r2 (lldb) frame select --relative -3 (lldb) fr s -r-3
(gdb) info registers
(lldb) register read
123 to the current thread register rax(gdb) p $rax = 123
(lldb) register write rax 123
Note that we use backticks to evaluate an expression and insert the scalar result in LLDB.
(gdb) jump *$pc+8
(lldb) register write pc `$pc+8`
LLDB tries to use the same format characters as printf(3) when possible. Type “help format” to see the full list of format specifiers.
(lldb) register read --format i (lldb) re r -f i
LLDB now supports the GDB shorthand format syntax but there can't be space after the command:
(lldb) register read/d
(gdb) info all-registers
(lldb) register read --all (lldb) re r -a
rax, rsp and rbp in the current thread(gdb) info all-registers rax rsp rbp
(lldb) register read rax rsp rbp
rax in the current thread formatted as binary(gdb) p/t $rax
(lldb) register read --format binary rax (lldb) re r -f b rax
LLDB now supports the GDB shorthand format syntax but there can't be space after the command
(lldb) register read/t rax (lldb) p/t $rax
0xbffff3c0 and show 4 hex uint32_t values(gdb) x/4xw 0xbffff3c0
(lldb) memory read --size 4 --format x --count 4 0xbffff3c0 (lldb) me r -s4 -fx -c4 0xbffff3c0 (lldb) x -s4 -fx -c4 0xbffff3c0
LLDB now supports the GDB shorthand format syntax but there can't be space after the command:
(lldb) memory read/4xw 0xbffff3c0 (lldb) x/4xw 0xbffff3c0 (lldb) memory read --gdb-format 4xw 0xbffff3c0
argv[0](gdb) x argv[0]
(lldb) memory read `argv[0]`
NOTE: any command can inline a scalar expression result (as long as the target is stopped) using backticks around any expression:
(lldb) memory read --size `sizeof(int)` `argv[0]`
512 bytes of memory from address 0xbffff3c0 and save the results to a local file as text(gdb) set logging on (gdb) set logging file /tmp/mem.txt (gdb) x/512bx 0xbffff3c0 (gdb) set logging off
(lldb) memory read --outfile /tmp/mem.txt --count 512 0xbffff3c0 (lldb) me r -o/tmp/mem.txt -c512 0xbffff3c0 (lldb) x/512bx -o/tmp/mem.txt 0xbffff3c0
0x1000 and ending at 0x2000 to a file(gdb) dump memory /tmp/mem.bin 0x1000 0x2000
(lldb) memory read --outfile /tmp/mem.bin --binary 0x1000 0x2000 (lldb) me r -o /tmp/mem.bin -b 0x1000 0x2000
(gdb) info proc mappings
(lldb) memory region --all (lldb) me reg --all
(gdb) info malloc 0x10010d680
(lldb) command script import lldb.macosx.heap (lldb) process launch --environment MallocStackLogging=1 -- [ARGS] (lldb) malloc_info --stack-history 0x10010d680
(lldb) command script import lldb.macosx.heap (lldb) malloc_info --type 0x10010d680
EXPR (macOS only)(lldb) command script import lldb.macosx.heap (lldb) ptr_refs EXPR
(lldb) command script import lldb.macosx.heap (lldb) cstr_refs CSTRING
(gdb) disassemble
(lldb) disassemble --frame (lldb) di -f
(gdb) disassemble main
(lldb) disassemble --name main (lldb) di -n main
(gdb) disassemble 0x1eb8 0x1ec3
(lldb) disassemble --start-address 0x1eb8 --end-address 0x1ec3 (lldb) di -s 0x1eb8 -e 0x1ec3
20 instructions from a given address(gdb) x/20i 0x1eb8
(lldb) disassemble --start-address 0x1eb8 --count 20 (lldb) di -s 0x1eb8 -c 20
(lldb) disassemble --frame --mixed (lldb) di -f -m
(lldb) disassemble --frame --bytes (lldb) di -f -b
(lldb) disassemble --line (lldb) di -l
(gdb) info shared
(lldb) image list
(gdb) info symbol 0x1ec4
(lldb) image lookup --address 0x1ec4 (lldb) im loo -a 0x1ec4
(gdb) info function <FUNC_REGEX>
This one finds debug symbols:
(lldb) image lookup -r -n <FUNC_REGEX>
This one finds non-debug symbols:
(lldb) image lookup -r -s <FUNC_REGEX>
Provide a list of binaries as arguments to limit the search.
(gdb) info line 0x1ec4
This one is a bit messy at present. Do:
(lldb) image lookup -v --address 0x1ec4
and look for the LineEntry line, which will have the full source path and line range information.
a.out only(lldb) image lookup --address 0x1ec4 a.out (lldb) im loo -a 0x1ec4 a.out
Point by name(gdb) ptype Point
(lldb) image lookup --type Point (lldb) im loo -t Point
(gdb) maintenance info sections
(lldb) image dump sections
a.out module(lldb) image dump sections a.out
(lldb) image dump symtab
a.out and liba.so(lldb) image dump symtab a.out liba.so
(gdb) gcore filename
(lldb) process save-core filename
(gdb) apropos keyword
(lldb) apropos keyword
(gdb) echo Here is some text\n
(lldb) script print("Here is some text")
If your source files are no longer located in the same location as when the program was built (for example, if the program was built on a different computer) you need to tell the debugger how to find the sources at their local file path instead of the build system's file path.
(gdb) set pathname-substitutions /buildbot/path /my/path
(lldb) settings set target.source-map /buildbot/path /my/path
(gdb) directory /my/path
There is no equivalent LLDB command, use target.source-map instead.