164 – LLDB实用 – 重新认识breakpoint

20. 六月 2019 iOS 0

写这篇文章的目的是重新认识Xcode中的断点操作,除了在Xcode中的show the breakpoint navigator可以添加一些短点,我们还可以在lldb中使用命令进行断点的增删改查。

1.认识breakpoint

我们还是通过lldb的help breakpoint来认识断点的相关执行方法,

可以看到和watchpoint的子命令差不多,我们根据平时使用的方式来学习breakpoint的实用知识。

2.断点(条件断点,符号断点,一次性断点,内存断点)

这篇文章就狭义的讨论OC的断点,C++的方法断点breakpoint set --method main和符号断点breakpoint set --basename main(–basename将忽略C++中的namespace和参数)等不再讨论。

2.1断点的设置 breakpoint set

断点的设置大家都很清楚,因为在Xcode中打断点,就是在代码左侧点一下就可以了。
我们用lldb,断点的设置命令就是breakpoint set,但是由于set的子命令还有很多

所以,我们在Xcode中点击左侧的断点在lldb中怎么打的呢?
文件行数断点:breakpoint set --file ViewController.m --line 15,这个在ViewController文件中,第15行的断点

2.2符号断点(symbolic breakpoint)

在Xcode的断点导航窗口,+号中,可以看到symbolic breakpoint的选项,点击创建后我们可以看到,在symbol中可以填写类和方法名。

在lldb中,我们使用breakpoint set --name "-[UIViewController dismissViewControllerAnimated:completion:]"来设置符号断点

2.3 组合断点

上面讲了Xcode中的断点设置,文件断点,我们可以看到就是一个断点的组合命令--file--line
还有一些很常用的断点打法,可以组合起来使用,因为breakpoint set这个命令的子命令很多,就不一一举例了。

条件断点:--condition,比如我想在aStr在被赋值的情况下进入changeTitle函数:breakpoint set --address 0x000000010e888fd0 --condition "_aStr.length > 0",这里我已经知道了方法的地址

一次性断点:--one-shot,使用的时候配合其他指令,比如,我只关心在aStr有数据时第一次进入changeTitle的表现,那么breakpoint set --name "-[OtherViewController changeTitle]" 0x000000010e888fd0 --condition "_aStr.length > 0" --one-shot true

3.配合command使用(断点行为)

上一章,我们使用watchpoint,其实有说过一些实用中,使用代码注入。
这些行为,包括一些打印当前的frame,读取当前的寄存器数据,或者跳过一行代码,或者执行了这些操作后,你需要继续执行代码。
我们就可以用到 breakpoint command add 断点ID 这个方式来处理这些行为

删除断点上的命令 breakpoint command delete 断点ID

4.断点的修改(modify)

上面已经说了可以添加条件断点、一次性断点,等等操作。但是,我们很多时候不是一次性就能通过断点解决bug,还需要不断的改进断点,来更方便的使用。这时,我们就需要用到modify这个次级命令。
例如,发现在cellforrow的断点,你需要加一个row的判断条件,可以这样写breakpoint modify --condition "indexPath.row == 3" 1,最后面的数字是断点的序号。
再次执行时,就可以等到满足条件时,执行断点了。

5.场景

其他一些断点,与我们平时使用Xcode的工具打的差不多,这里不做讨论。
主要为符号断点需要我们熟练掌握并且在更多的场景中使用

5.1符号断点的使用

符号断点的主要用途是打断点在方法上,如果方法被调用,就会触发断点,可以配合“bt”(当前的调用栈)指令,查看到调用栈。
打法:

  1. breakpoint set –name dealloc ,断点会找出所有名称为dealloc的方法 (包含OC 和 C++)
  2. breakpoint set –name [NSObject dealloc ],断点可以在出某个类中实现的方法
  3. breakpoint set –selector dealloc ,断点在objc的方法
  4. breakpoint set –method dealloc ,断点在C++方法上

场景:当你有一个VC,这个VC如果被另一个开发给dismiss掉,使用符号断点可以轻松找到调用栈,然后找出是谁调用的,最后找出的调用者。
备注:如果需要查看是在代码的第几行,可以使用image lookup --address XXX(调用栈地址),打印出在什么文件的第几行。

5.2异常断点的扩展

-w <boolean>-h <boolean>参数来指定这个异常断点具体停下的位置。-w表示是否在异常被throW的时候停下,-h表示是否在异常被catcH的时候停下,具体使用的时候要跟-E language一起使用
breakpoint set -E objc -w true -h true

6.总结

//断点打在@property上,事实上是断点在get和set函数上v
//list命令