LLDB 和 GDB对照
1.1启动一个没有参数的进程。
GDB | LLDB |
run r | process launch run r |
1.2启动带有参数的进程。
GDB | LLDB |
run <args> r <args> | process launch -- <args> run <args> r <args> |
或者
GDB | LLDB |
set args 1 2 3 run | settings set target.run-args 1 2 3 run |
1.3在新终端窗口中启动带有参数的进程(仅限 macOS)。
process launch --tty -- <args>
or
pro la -t -- <args>
1.3.1在现有终端中启动带有参数的进程(仅限 macOS)
process launch --tty=/dev/ttys006 -- <args>
or
pro la -t/dev/ttys006 -- <args>
1.4 在启动之前设置进程的环境变量。
GDB | LLDB |
set env DEBUG 1 | settings set target.env-vars DEBUG=1 or set se target.env-vars DEBUG=1 or env DEBUG=1 |
1.4.1在启动之前取消设置进程的环境变量。
GDB | LLDB |
unset env DEBUG | settings remove target.env-vars DEBUG set rem target.env-vars DEBUG |
1.5 显示运行时将传递或已传递给程序的参数。
GDB | LLDB |
show args | settings show target.run-args |
1.6在一个命令中为进程和启动进程设置环境变量。
GDB | LLDB |
process launch -E DEBUG=1 |
1.7 附加到进程 ID 为 123 的进程。
GDB | LLDB |
attach 123 | process attach --pid 123 attach -p 123 |
1.8附加到名为“a.out”的进程。
GDB | LLDB |
attach a.out | process attach --name a.out pro at -n a.out |
GDB | LLDB |
等待名为“a.out”的进程启动并附加。 | |
attach -waitfor a.out | process attach --name a.out --waitfor pro at -n a.out -w |
连接在系统“eorgadd”(端口 8000)上运行的远程 gdb 协议服务器。 | |
target remote eorgadd:8000 | gdb-remote eorgadd:8000 |
连接到本地系统上运行的远程 gdb 协议服务器,端口 8000。 | |
target remote localhost:8000 | target remote localhost:8000 |
在系统“eorgadd”上以 kdp 模式连接到Darwin 内核。 | |
kdp-reattach eorgadd | kdp-remote eorgadd |
在当前选定的线程中执行源级单步。 | |
step s | thread step-in step s |
在当前选定的线程中执行源代码级别的单步执行。 | |
next n | thread step-over next n |
在当前选定的线程中执行指令级单步。 | |
stepi si | thread step-inst si |
在当前选定的线程中执行指令级单步执行。 | |
nexti ni | thread step-inst-over ni |
跳出当前选定的帧。 | |
finish | thread step-out finish |
立即从当前选定的帧返回,并带有可选的返回值。 | |
return <RETURN EXPRESSION> | thread return <RETURN EXPRESSION> |
每次停止时打印调用栈和显示汇编。 | |
target stop-hook add Enter your stop hook command(s). Type 'DONE' to end. > bt > disassemble --pc > DONE Stop hook #1 added. | |
运行直到第 12 行或控制离开当前函数。 | |
until 12 | thread until 12 |
显示当前帧和源行。 | |
frame | frame select f process status |
在名为 main 的所有函数上设置断点。 | |
break main | breakpoint set --name main br s -n main b main |
在文件 test.c 的第 12 行设置断点。 | |
break test.c:12 | breakpoint set --file test.c --line 12 br s -f test.c -l 12 b test.c:12 |
在基名称为 main 的所有方法C++设置断点。 | |
break main | breakpoint set --method main br s -M main |
在 Objective-C 函数 -[NSString stringWithFormat:] 处设置断点。 | |
break -[NSString stringWithFormat:] | breakpoint set --name "-[NSString stringWithFormat:]" b -[NSString stringWithFormat:] |
在选择器为 count 的所有 Objective-C 方法上设置断点。 | |
break count | breakpoint set --selector count br s -S count |
通过函数名称上的正则表达式设置断点。 | |
rbreak regular-expression | breakpoint set --func-regex regular-expression br s -r regular-expression |
Ensure that breakpoints by file and line work for #include .c/.cpp/.m files. | |
b foo.c:12 | settings set target.inline-breakpoint-strategy always 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 |
设置条件断点。 | |
break foo if strcmp(y,"hello") == 0 | breakpoint set --name foo --condition '(int)strcmp(y,"hello") == 0' br s -n foo -c '(int)strcmp(y,"hello") == 0' |
列出所有断点。 | |
info break | breakpoint list br l |
删除断点。 | |
delete 1 | breakpoint delete 1 br del 1 |
禁用断点 | |
disable 1 | (lldb) breakpoint disable 1 (lldb) br dis 1 |
启用断点 | |
enable 1 | (lldb) breakpoint disable 1 (lldb) br dis 1 |
在写入变量时设置变量的观察点。 | |
watch global_var | (lldb) watchpoint set variable global_var (lldb) wa s v global_var |
在写入内存位置时设置观察点。如果未指定“-x byte_size”,则要监视的区域大小默认为指针大小。此命令采用原始输入,计算为返回指向区域开头的无符号整数的表达式,位于“--”选项终止符之后。 | |
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 | |
列出所有观察点。 | |
info break | watchpoint list watch l |
删除观察点。 | |
delete 1 | (lldb) watchpoint delete 1 (lldb) watch del 1 |
显示当前帧的参数和局部变量 | |
(gdb) info args and (gdb) info locals | (lldb) frame variable (lldb) fr v |
显示当前帧的局部变量。 | |
info locals | (lldb) frame variable --no-args (lldb) fr v -a |
显示局部变量“bar”的内容。 | |
p bar | (lldb) frame variable bar (lldb) fr v bar (lldb) p bar |
显示格式化为十六进制的局部变量“bar”的内容。 | |
p/x bar | (lldb) frame variable --format x bar (lldb) p bar fr v -f x bar |
显示全局变量“baz”的内容。 | |
p baz | (lldb) target variable baz (lldb) ta v baz |
显示当前源文件中定义的全局/静态变量。 | |
n/a | (lldb) target variable (lldb) ta v |
每次停止时显示变量“argc”和“argv”。 | |
(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 |
仅当您在名为 main 的函数中停止时,才显示变量 “argc” 和 “argv”。 | |
(lldb) target stop-hook add --name main --one-liner "frame variable argc argv" (lldb) ta st a -n main -o "fr v argc argv" | |
仅当您在名为 MyClass 的 c 类中停止时,才显示变量“*this”。 | |
(lldb) target stop-hook add --classname MyClass --one-liner "frame variable *this" (lldb) ta st a -c MyClass -o "fr v *this" | |
在内存中打印一个整数数组,假设我们有一个像“int *ptr”这样的指针。 | |
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 |
打印对象的 ObjC“描述”。 | |
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) expr -d 1 -- [SomeClass returnAnObject] (lldb) expr -d 1 -- someCPPObjectPtrOrReference or set dynamic type printing to be the default: (lldb) settings set target.prefer-dynamic run-target |
调用函数,以便可以在其中的断点处停止。 | |
(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() |
1.9检查线程状态
GDB | LLDB |
列出程序中的线程。 | |
(gdb) info threads | (lldb) thread list |
选择线程 1 作为后续命令的默认线程。 | |
(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 (lldb-169 and later) (lldb) bt -c 5 (lldb-168 and earlier) |
为当前线程按索引选择不同的堆栈帧。 | |
(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”写入当前线程寄存器“rax”。 | |
(gdb) p $rax = 123 | (lldb) register write rax 123 |
跳过当前程序计数器(指令指针)前面的 8 个字节。请注意,我们使用反引号来计算表达式并在 LLDB 中插入标量结果。 | |
jump *$pc+8 | (lldb) register write pc `$pc+8` |
显示格式化为有符号十进制的当前线程的常规用途寄存器。LLDB 尽可能尝试使用与 printf(3) 相同的格式字符。键入“帮助格式”以查看格式说明符的完整列表。 | |
(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”和“rbp”的寄存器的值。 | |
(gdb) info all-registers rax rsp rbp | (lldb) register read rax rsp rbp |
显示格式化为二进制的当前线程中名为“rax”的寄存器的值。 | |
(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读取内存并显示 4 个十六进制值。uint32_t | |
(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]` |
从地址512xbffff0c3读取 0 字节的内存,并将结果作为文本保存到本地文件。 | |
(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 开始到0x2000结束的二进制内存数据保存到文件中。 | |
(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 |
获取有关特定堆分配的信息(仅在 macOS 上可用)。 | |
(gdb) info malloc 0x10010d680 | (lldb) command script import lldb.macosx.heap (lldb) process launch --environment MallocStackLogging=1 -- [ARGS] (lldb) malloc_info --stack-history 0x10010d680 |
获取有关特定堆分配的信息,并将结果转换为可推断的任何动态类型(仅在 macOS 上可用) | |
(lldb) command script import lldb.macosx.heap (lldb) malloc_info --type 0x10010d680 | |
查找包含表达式 EXPR 指定的指针的所有堆块(仅在 macOS 上可用)。 | |
(lldb) command script import lldb.macosx.heap (lldb) ptr_refs EXPR | |
在块中的任何位置查找包含 C 字符串的所有堆块(仅在 macOS 上可用)。 | |
(lldb) command script import lldb.macosx.heap (lldb) cstr_refs CSTRING | |
反汇编当前帧的当前函数。 | |
(gdb) disassemble | (lldb) disassemble --frame (lldb) di -f |
反汇编任何名为 main 的函数。 | |
(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 条指令。 | |
(gdb) x/20i 0x1eb8 | (lldb) disassemble --start-address 0x1eb8 --count 20 (lldb) di -s 0x1eb8 -c 20 |
显示当前帧的当前函数的混合源和反汇编。 | |
n/a | (lldb) disassemble --frame --mixed (lldb) di -f -m |
反汇编当前帧的当前函数并显示操作码字节。 | |
n/a | (lldb) disassemble --frame --bytes (lldb) di -f -b |
反汇编当前帧的当前源行。 | |
n/a | (lldb) disassemble --line (lldb) di -l |
1.10可执行和共享库查询命令
GDB | LLDB |
列出主可执行文件和所有依赖的共享库。 | |
(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 中查找地址信息。 | |
(lldb) image lookup --address 0x1ec4 a.out (lldb) im loo -a 0x1ec4 a.out | |
按名称查找类型的信息Point | |
(gdb) ptype Point | (lldb) image lookup --type Point (lldb) im loo -t Point |
转储主可执行文件和任何共享库中的所有部分。 | |
(gdb) maintenance info sections | (lldb) image dump sections |
转储 a.out 模块中的所有部分。 | |
(lldb) image dump sections a.out | |
从主可执行文件和任何共享库中转储所有符号。 | |
(lldb) image dump symtab | |
将所有符号转储到 a.out 和 liba.so。 | |
(lldb) image dump symtab a.out liba.so |
1.11 杂项
GDB | LLDB |
搜索关键字的命令帮助。 | |
(gdb) apropos keyword | (lldb) apropos keyword |
将文本回显到屏幕。 | |
(gdb) echo Here is some text\n | (lldb) script print "Here is some text" |
重新映射调试会话的源文件路径名。如果源文件不再位于生成程序时的位置(例如,如果程序是在其他计算机上生成的),则需要告诉调试器如何在其本地文件路径而不是生成系统的文件路径中查找源。 | |
(gdb) set pathname-substitutions /buildbot/path /my/path | (lldb) settings set target.source-map /buildbot/path /my/path |
提供一个用于在其中搜索源文件的包罗万象目录。 | |
(gdb) directory /my/path |