LLDB Study Notes

  1. Comparison between LLDB and GDB

1.1 Start a process with no arguments.

GDB

LLDB

run

r

process launch

run

r

1.2 Start the process with parameters.

GDB

LLDB

run <args>

r <args>

process launch -- <args>

run <args>

r <args>

or

GDB

LLDB

set args 1 2 3

run

settings set target.run-args 1 2 3

run

1.3 Start a process with arguments in a new terminal window (macOS only).

process launch --tty -- <args>
or
pro la -t -- <args>

1.3.1 Start a process with arguments in an existing terminal (macOS only)

process launch --tty=/dev/ttys006 -- <args>
or
pro la -t/dev/ttys006 -- <args>

1.4 Set the environment variables of the process before starting.

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 Unset the environment variable of the process before starting it.

GDB

LLDB

unset env DEBUG

settings remove target.env-vars DEBUG

set rem target.env-vars DEBUG

1.5 Shows the arguments that will be passed or have been passed to the program at runtime.

GDB

LLDB

show args

settings show target.run-args

1.6 Set environment variables for process and start process in one command.

GDB

LLDB

process launch -E DEBUG=1

1.7 Attach to process with process ID 123.

GDB

LLDB

attach 123

process attach --pid 123

attach -p 123

1.8 attaches to a process named "a.out".

GDB

LLDB

attach a.out

process attach --name a.out

pro at -n a.out

GDB

LLDB

Wait for a process named "a.out" to start and attach.

attach -waitfor a.out

process attach --name a.out --waitfor

pro at -n a.out -w

Connect to a remote gdb protocol server running on system "eorgadd" (port 8000).

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.outliba.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

Guess you like

Origin blog.csdn.net/slbwgslz/article/details/129238766