LLDB总结

本文介绍了一系列使用LLDB进行iOS应用调试的方法,包括打印视图层级、线程状态、寄存器信息、对象描述等,还提供了更新UI和控制流程的具体指令。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1Facebook 发布了一组名为 Chisel 的 Python 脚本集合,可以试一下

2打印出完整的视图层次结构。

po [[UIWindow keyWindow] recursiveDescription]
po [[[UIWindow keyWindow] rootViewController] _printHierarchy]       (IOS8及以上)

3打印线程状态

bt / bt all

4打印寄存器

Objective-C 方法都有两个隐式参数:self 和 _cmd。于是我们所需要的就是在栈上的第一个对象。在 32-bit 架构中,栈信息保存在 espObjectiveC使po(int)(esp+4) 来获取 self,以及使用 p (SEL)(int)(esp+8)cmdesp 里的第一个值是返回地址。随后的变量保存在 esp+12esp+16 以及依此类推的其他位置上。

x86-64 架构 (那些包含 arm64 芯片 iPhone 设备的模拟器) 提供了更多寄存器,所以变量放置在 rdirsi,rdxrcx,r8r9 中。所有后续的变量在 rbprbp+16,$rbp+24 等。

armv7 架构的变量通常放置在 r0r1,r2r3 中,接着移动到 $sp 栈上:

arm64 类似于 armv7,然而,因为有更多的寄存器,从 x0x7 的整个范围都用来存放变量,之后回到栈寄存器 $sp 中。

你可以学到更多关于 x86,x86-64 的栈布局知识,还可以阅读 AMD64 ABI Draft 来进行深入。

5打印一个值

print/p

6改变一个值

expression

7打印对象的 description

po

8打印变量的不同格式

print/ 或者简化的 p/
默认的格式

(lldb) p 16
16

十六进制:

(lldb) p/x 16
0x10

二进制 (t 代表 two):

(lldb) p/t 16
0b00000000000000000000000000010000
(lldb) p/t (char)16
0b00010000

你也可以使用 p/c 打印字符,或者 p/s 打印以空终止的字符串 (译者注:以 ‘\0’ 结尾的字符串)。
这里是格式的完整清单。

9流程控制

continuestep over,step intostep out,finish

10当前的行数和源码

frame info

11thread return

调试时,还有一个很棒的函数可以用来控制程序流程:thread return 。它有一个可选参数,在执行时它会把可选参数加载进返回寄存器里,然后立刻执行返回命令,跳出当前栈帧。这意味这函数剩余的部分不会被执行。这会给 ARC 的引用计数造成一些问题,或者会使函数内的清理部分失效。但是在函数的开头执行这个命令,是个非常好的隔离这个函数,伪造返回值的方式 。

让我们稍微修改一下上面代码段并运行:

p i
s
thread return NO
n
p even0
frame info

12条件断点,符号断点,断点action

13更新UI

有了上面的输出,我们可以获取这个 view:

(lldb) e id $myView = (id)0x7f82b1d01fd0

然后在调试器中改变它的背景色:

(lldb) e (void)[$myView setBackgroundColor:[UIColor blueColor]]

但是只有程序继续运行之后才会看到界面的变化。因为改变的内容必须被发送到渲染服务中,然后显示才会被更新。

渲染服务实际上是一个另外的进程 (被称作 backboardd)。这就是说即使我们正在调试的内容所在的进程被打断了,backboardd 也还是继续运行着的。

这意味着你可以运行下面的命令,而不用继续运行程序:

(lldb) e (void)[CATransaction flush]

即使你仍然在调试器中,UI 也会在模拟器或者真机上实时更新。Chisel 为此提供了一个别名叫做 caflush,这个命令被用来实现其他的快捷命令,例如 hide ,show 以及其他很多命令。所有 Chisel 的命令都有文档,所以安装后随意运行 help show 来看更多信息。

14Push 一个 View Controller

想象一个以 UINavigationController 为 root ViewController 的应用。你可以通过下面的命令,轻松地获取它:

(lldb) e id $nvc = [[[UIApplication sharedApplication] keyWindow] rootViewController]

然后 push 一个 child view controller:

(lldb) e id $vc = [UIViewController new]
(lldb) e (void)[[$vc view] setBackgroundColor:[UIColor yellowColor]]
(lldb) e (void)[$vc setTitle:@"Yay!"]
(lldb) e (void)[$nvc pushViewContoller:$vc animated:YES]

最后运行下面的命令:

(lldb) caflush // e (void)[CATransaction flush]

navigation Controller 就会立刻就被 push 到你眼前。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值