Github博客位置: https://nasdaqgodzilla.github.io/2019/02/24/LLDB%E8%BF%9C%E7%A8%8B%E8%B0%83%E8%AF%95Android%EF%BC%9ALLDB%E5%91%BD%E4%BB%A4%E9%80%9F%E6%9F%A5%E5%8F%82%E8%80%83%E6%89%8B%E5%86%8CHandbook/
远程调试Android Device
Android端启动lldb server
在此之前将lldb server push到设备,如/data/loca/tmp
lldb-server platform \
--server --listen unix-abstract:///data/local/tmp/debug.sock
后台运行:
lldb-server platform \
--server --listen unix-abstract:///data/local/tmp/debug.sock &
Host端连接lldb server
在此之前必须先通过adb连接上Android
$ lldb # 启动lldb
(lldb) platform select remote-android # 选择远程调试Android
Platform: remote-android
Connected: no
(lldb) platform connect unix-abstract-connect:///data/local/tmp/debug.sock # 连接lldb server
Platform: remote-android
Triple: arm-*-linux-android
OS Version: 29.0.0 (4.14.141+)
Kernel: #27 SMP PREEMPT Mon Mar 14 18:24:42 CST 2020
Hostname: localhost
Connected: yes
WorkingDir: /data/local/tmp
Host端附加remote Android进程
(lldb) process attach -p 1
Process 1 stopped
* thread #1, name = 'init', stop reason = signal SIGSTOP
frame #0: 0xffffffffffffffff
Architecture set to: arm--linux-android.
技巧:用好tab,所有命令和参数都能使用tab很轻松的补全;用好命令和参数的简写。
LLDB Cheat Sheet
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-j42tfQYq-1655815844973)(https://cdn.jsdelivr.net/gh/NasdaqGodzilla/PeacePicture/img/LLDBCheatSheet1.jpg)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jIpyS0Oc-1655815844975)(https://cdn.jsdelivr.net/gh/NasdaqGodzilla/PeacePicture/img/LLDBCheatSheet1.jpg)]
LLDB命令格式
命令 + 子命令 + 命令选项 + 命令参数
<command> [<subcommand> [<subcommand>...]] <action> [-options [optionvalue]] [argument [argument...]]
breakpoint调试断点
breakpoint set --file abort.c --line 12
breakpoint set -f syscall.S -l 12
breakpoint set --name abort
breakpoint set -n assert
breakpoint set --func-regex abort
breakpoint set --address 0xf2dbd03e
breakpoint set -a 0xf2dbd03e
breakpoint set --shlib liblog.so --name _log
- 查看已经设置的断点,注意看输出信息包含断点是否成功命中、是否enable、进程中有多少个位置命中断点:
(lldb) breakpoint list
(lldb) breakpoint disable 1 # 对断点1进行操作
(lldb) breakpoint enable 1
(lldb) breakpoint delete 1
(lldb) breakpoint delete all # 删除所有断点
thread线程操作/backtrace/bt
thread list
thread backtrace
bt # 上一条命令的简写
thread backtrace all
thread select n # 选择指定的线程号
thread continue/continue/c
thread step-over/next/n
thread step-into/step/s
thread step-out/finish
thread return 10
可以通过backtrace 或bt 直接打印堆栈。
frame栈帧操作
frame info
frame select n # 选择栈帧
frame up # 向上一层栈帧
frame down
frame variable # 打印当前栈帧的变量
image镜像操作
列出进程加载的库
image list
查找指定的地址信息
image lookup --type
image lookup -t
image lookup --name
image lookup -n
image lookup --address
image lookup -a
通过函数名或符号名查找对应的地址
image lookup -r -n <FUNC_REGEX> # 有符号时使用
image lookup -r -s <FUNC_REGEX> # 无符号时使用
dump
image dump sections
image dump sym
watchpoint调试断点
针对变量、内存地址进行设置:
watchpoint set variable valName # 代码中的变量名
watchpoint set variable self->_dataArray
watchpoint set expression 0x14AD6A70
在此基础上添加条件(Read、Write):
watchpoint set expression -w read -- 0x16aabbcc # 内存地址 注意--
watchpoint set expression -w write -- 0x16aabbcc
条件断点:
watchpoint modify -c '*(int *)0x10aabbcc == 1'
watchpoint list
watchpoint delete i
watchpoint delete all
流程控制
r # run
run # 运行程序
c # process continue
process continue # 继续
process interupt # 暂停
s # strp
step # 源码级别的单步执行/进入函数
stepi # 汇编指令级别的单步执行/进入函数
next # 同step但不进入函数
nexti # 同stepi但不进入函数
finish # 完成执行当前函数(执行完成当前函数的所有剩余指令并退出到上一级)
return # 直接退出当前函数,可以指定返回值
memory内存操作
memory read [起始地址 结束地址]/寄存器 -outfile 输出路径(内存操作)
memory read $pc
Memory操作比较复杂,建议直接查看官方手册或Cheat Sheet。
disassemble:显示汇编代码
disassemble -b
disassemble --frame
disassemble --name func_name
disassemble -a address
disassemble -s address
d # 这三行都是等价简写
di
dis
register寄存器操作
读写寄存器:
register read
register read r0
register write r10 1 # 寄存器名称 写入值
expression/print
打印指定变量或表达式。
简写po ,等同于expression -O 。
print根据变量名打印值。
display变量观察列表
- display:类似IDE提供的watch list。每次单步执行后都会打印出指定的表达式的值。
display expr
display list
undisplay n
help
(lldb) help
(lldb) help frame
参考
- LLDB官网
- Apple Developer LLDB command examples
|