断点调试
文章来源:http://www.hotobear.com/?p=511
自定义断点
Xcode中,断点右键,选择“Edit Breakpoint…”,可以看见如下的视图:
- Condition:条件断点,用来对付遍历或者循环相当有效
- Ignore:忽略前多少次的断点
- Action:断点时执行某种操作。右面的“+”“-”可以添加删除其他操作。点开下拉框,一共有六种操作可以选择
- Debugger Command:Debugger指令,提示可以填入“po foo”之类的指令。Debugger指令高深莫测,具体等以后总结GDB和LLDB时再详细讲讲
- Log Message:日志输出,一些特殊的日志规则也都有提示。(日志输出可以选择语音哦,识别率很高声音很性感哦)
- Shell Command:Shell指令,没有具体尝试过,估计对于自动化测试很有效果
- Sound:声音,和语音日志输出一样,就是用来调戏用的
- 其他两种,目前没有应用场景,先占位
4.Options:勾选可以选择执行后自动跳过。话说自动跳过的断点有什么用,其实是用来配合上一项“Action”的,这两项配合得好的话,必杀技无疑了
更多类型的断点
断点的导航视图(快捷键Command+6),详细标明了程序里的断点信息。除了第一种之外,还有两种:异常断点和符号断点,如下图。具体可在左下角的“+”添加。
-
异常断点(Exception Breakpoint)
假如我们执行下面的代码:
NSArray *array = [[NSArray alloc] init]; NSObject *i = [array objectAtIndex:0]; NSLog(@"%@", i);
会直接崩溃到main函数数并报异常。虽说可以知道是什么异常,但没法立刻知道具体是哪里抛出了异常,这时,添加一个异常断点就十分有效了。
添加一个异常断点。“Break”选择“On Throw”,再次运行代码,就可以在第二句代码处抛出异常时断点。
-
符号断点(Symbolic Breakpoint)
- 假设此时需要断点在非自己的代码的函数里面,这一项就发挥作用了。
- Symbol:符号,假如断不到点,可以先确定下是否格式写错了
- Module:模块,限制范围用的
- 其他选项的和之前的相同
堆栈
断点生效之后,按Command+5,可以快速跳到堆栈的导航视图,如下图:
- Thread 1是主线程,也就是常说的UI线程,能够看到的是一个runloop开始到断点之间的堆栈调用的函数符号,按照调用顺序排列,最底部是从main函数向UIApplication发出的runloop开始的调用,一般来说基本没什么参考意义
- 不同的库和framework的堆栈用不同的颜色来表示,蓝色的人头表示的是非系统库的堆栈,紫色的杯子就是UIKit的东西啦
- 看得见函数名称的,说明拥有符号表,没有呢就靠猜吧,当然控制台lldb也是可以打印的
主线程被卡住是非常常见的场景,具体表现就是程序不响应任何的UI交互。这时按下调试的暂停按钮,查看堆栈,就可以看到是到底是死锁、死循环还是死等,导致UI线程被卡住。