调试程序-断点,Debug,崩溃日志分析,友盟崩溃日志

本文详细介绍了Xcode中的各种调试技巧,包括如何设置和查看不同类型的断点、使用调试工具栏进行变量查看、利用日志与断言输出进行调试、掌握LLDB调试工具的基本命令、分析异常堆栈报告及符号化设备的崩溃日志等。
摘要由CSDN通过智能技术生成
一.设置和查看断点
断点可以分为以下3种类型。
1. 文件行断点设置
添加断点->右键选择Edit Breakpoint



Condition:指的是条件表达式,该项允许我们对断点生效设置条件,表示当满足某一特定条件的前提下,该断点才生效。(该条件的录入,不能够识别预处理的宏定义,也不能识别断点作用域之外的变量和方法)。eg:i == 1 ; (i == 1 || i == 2)

Ignore:忽略次数。它指定了在断点生效,应用暂停之前,代码忽略断点的次数。你如果希望应用运行一段时间后断点才生效,那么就可以使用这个选项。比如说在调试某一循环体的时候。eg:Ignore 2 == 前两次执行此处的代码不会触发该断点,从第三次开始触发该断点。如果数字为n,则从第n次开始触发该断点。

Action:动作。它表示当断点生效时,Xcode作出反应后的行为动作。点击右边的Add Action选项会弹出如图

图中所示红色方框中的选项,可以让你指定那一种动作。默认的是Debugger Command。还有以下几种动作供选择,下面逐一介绍。
它是苹果提供的一种脚本语言,用来执行一些预先指定的行为。选中该选项,将会出现如图所示的AppleScript语言的输入框。


大家可能看到了,我在输入框中输入了本门至高无上的心法秘诀,它的意思是弹出一个显示“Hello World!”的对话框。点击Compile按钮后,如果没有错误,会显示成功信息。而点击Test按钮,会测试运行效果,如下图


至于红色方框中的内容是三种特殊符号相对应的定义。

符号标记定义
@expression @LLDB表达式
%B断点的名称
%H遇到该断点的次数

(2).Capture GPU Frame
这个功能用于当断点生效时,捕获GPU当前所绘制的帧。该功能是辅助图形调试的。

(3).Debugger Command
默认的选项,可以让断点执行LLDB调试命令。

po _imageArray 打印该断点上面用到的数组内容

(4).Log Message
使用Log命令可以生成消息队列,将相关的消息输出到控制台上,还有一个Speak Message选项,可以播报消息。


(5).Shell Command
该动作接收一个命令文件和参数列表。如下图所示


命令文件必须是一个可执行的二进制程序或者脚本。可以复制粘贴输入路径,也可以点击Choose按钮选择具体文件。
参数通过空格表示分割,也可以在两个@字符之间包含LLDB表达式。
一般情况下,Xcode会异步执行Shell Command,也就是说,Shell Command 和调试器将会同步执行。如果希望调试器在Shell Command命令完成后运行,则可以勾选下面的Wait until done选项。

(6).Sound
动作会在断点被触发时,弹出声音提示。



Options: 在执行完事件之后自动继续执行。选中该选项之后,程序不会止步于该断点,遇到该断点也会继续执行,但是会响应action中的调试信息。

2. 符号断点设置
设置符号断点与设置文件行断点不同,需要点击导航面板中的按钮打开断点导航面板,如图 15-10 所示。
在断点导航面板中,可以看到所有的断点。


其中有两项 ——Add Symbolic Breakpoint Add Exception Breakpoint ,前者可以创建符号断点,后者可以创建异常断点。这里我们选择 Add Symbolic Breakpoint 菜单项,此时可以弹出创建符号断点对话框,如图


Symbol:后面可以是
1. 方法名称:会对所有具有此方法名称的类方法生效。例如 initWithFrame: 。 
2. 特定类的方法:OC类和C++类都适用,例如 ,[UIView initWithFrame:]或者 Shap::draw()。 
3. 函数名称。例如普通C函数。

Module:是模组的意思,用来限制满足符号的方法,编译器将只会在断点满足这个模组的符号的时候才回暂停

其余的选项同上。

3. 异常断点设置








Exception选项可以让你选择响应Objective-C对象抛出的异常,也可以选择响应C++对象抛出的异常。
Break则是选择断点所接收的异常,是接收“Throw”语句抛出的异常还是Catch语句的。

3.OpenGL ES错误断点(OpenGl ES Error Breakpoint)

这个断点的作用和异常断点类似,只不过这个断点只有在openGL ES错误发生的时候才会触发。


4.测试失败断点 Test Failure Breakpoint

仅在测试断点失败的时候才会执行,这个时候,应用将会暂停在引发测试失败的代码处,而不是停止在测试代码处。

二、调试工具栏



模拟位置按钮左边的为图层查看按钮,点击可以查看界面的各个图层

变量查看窗口

Auto。查看经常使用的变量。
Local Variables。查看本地变量。
Variables, Registers, Globals and Statics。查看全部变量,包括寄存器和全局变量等,如图 15-25 所示,
其中图标 A 是自动变量、 S 是静态变量、 R 是寄存器、 L 是本地变量。

Print Description of “i”  打印变量信息
Edit Value…    编辑变量的值


三、 日志与断言输出
1.使用NSLog函数
2. 使用NSAssert宏
NSLog 函数是无条件输出,即程序运行到该语句,就会输出结果。如果想有条件输出结果,可以使用 NSAssert
宏。注意, NSAssert 并不是函数,它的定义如下:
#define NSAssert(condition, desc, ...)
其中第一个参数 condition 是布尔表达式,第二个参数 desc 是描述信息,参数后面的 ... 是格式化 desc 描述信息
的。如果
condition NO ,则输出 desc 描述信息,并抛出异常 NSInternalInconsistencyException ;如果
condition YES ,则不输出信息。



2. 移除项目中的打印信息



(1)移除NSAssert




NS_BLOCK_ASSERTIONS Foundation 框架中定义好的预处理宏,如果在编译环境中设置 NS_BLOCK_ASSERTIONS 在编译的时候 NSAssert 宏将被移
(2) 移除NSLog


扩展: 
1.自己在pch文件中预定义如下宏
#ifdef MY_MACRO
#define NAME @
" 测试版本 "
#else
#define NAME @
" 上线版本 "
#endif
2.
设置preprocessor Macros—>Debug(添加 MY_MACRO=1)
3.在项目中使用NAME宏

如果项目Scheme编译模式为Debug  输出:name = 测试版本
如果项目Scheme编译模式为release 输出:name = 上线版本


四、LLDB调试工具
p po 就是调试工具的 命令,调试工具的编译器相对独立于 Xcode 。我们进行 Objective-C 程序开发时,用过 3 种编译器 ——GCC LLVM  GCC Apple LLVM ,其中 GCC 是比较古老的编译器,现在我们主要使用 LLVM GCC Apple LLVM GCC 的调试 工具是 GDB ,是 GCC Debug 工具的缩写, LLVM GCC Apple LLVM 的调试工具是 LLDB (或 lldb 进入 LLDB 调试工 具的一种方式是从终端进入,另外一种是从 Xcode 进入。 Xcode 工具我们比较熟悉,这里主要介绍这种方式。具体 做法很简单,就是在程序中设置断点,当程序挂起时,在输出窗口中选择 Debugger Output ,这时输出窗口有 (lldb)
命令提示符,这就进入了 LLDB 调试工具了。
常用命令:po

五、异常堆栈报告分析





[exception reason] 异常产生的原因
[exception callStackSymbols] 符号化打印


查看设备的崩溃日志


Window—>Devices—>View Device Logs

点击Re-Symbolicate Log 符号化日志信息
红色标注部分指出崩溃代码在ViewController0.m的第60行代码

六、符号化设备的崩溃日志
1.手动 符号化设备的崩溃日志

我们在ios开发中会碰到的很多crash问题,如果Debug调试模式的话,我们可以往往很容易的根据log的输出定位到导致crash的原因,但对于已经上线的应用,或者是release环境包导致的crash,我们就需要一些特殊的手段来通过crash log进行分析定位了。

通过参考网上的一些资料,总结了一下,下面介绍一下通过dSYM文件以及crash log分析定位的方法。

1.导出crash log

通过Xcode的Organizer查看某台iphone设备的DeviceLog,选择需要的crash log,导出XXX.crash文件。

2.找到对应的app文件

找到当前iphone设备上安装的ipa文件,更改文件后缀名为zip,解压后得到Payload文件夹,你需要的app文件就在其中了。

3.找到对应build版本的dSYM文件

dSYM文件是iOS编译后保存16进制函数地址映射信息的文件,每次应用程序build后,都会生成对应的xxx.app, xxx.app.dSYM文件。






4.确定dSYM、app以及crash文件的关系

首先将 dSYM、app以及crash放入同一个文件夹中,通过终端进入该文件夹。

每一个xx.app, xxx.app.dSYM文件都拥有相应的uuid,crash文件也有uuid,只有三者uuid一至才表明之三者可以解析出正确的日志文件。
查看xx.app文件的uuid的方法,在terminal中输入命令:

dwarfdump --uuid xxx.app/xxx (xxx工程名)

查看xx.app.dSYM文件的uuid的方法,在terminal中输入命令:

dwarfdump --uuid xxx.app.dSYM (xxx工程名)

而.crash的uuid位于,crash日志中的Binary Images:中的第一行尖括号内。如:

armv7 <8bdeaf1a0b233ac199728c2a0ebb4165>


5.通过symbolicatecrash分析crash文件

Xcode有自带的symbolicatecrash工具,可以通过dSYM文件将crash文件中的16进制地址转换成可读的函数地址。该文件是隐藏文件,可以通过如下命令查找并拷贝到系统目录下,并建立快捷方式。
1)打开终端,进入到symbolicatecrash工具所在的文件夹目录
第一步:找到 symbolicatecrash工具所在的文件夹目录
find /Applications/Xcode.app -name symbolicatecrash(速度快)
或者
find /Applications/Xcode.app -name symbolicatecrash -type f
运行结果
/Applications/Xcode.app/Contents/SharedFrameworks/DVTFoundation.framework/Versions/A/Resources/symbolicatecrash

第二步:进入该目录
cd  /Applications/Xcode.app/Contents/SharedFrameworks/DVTFoundation.framework/Versions/A/Resources/symbolicatecrash

2)查找确认是否存在symbolicatecrash(可省略)
ls -al | grep symbolicatecrash

bogon:Resources bang$ ls -al | grep symbolicatecrash
-rwxr-xr-x   1 root  wheel    37893  2 26 10:22 symbolicatecrash

3)将symbolicatecrash工具拷贝到 dSYM、app以及crash所在的文件夹
bogon:Crash bang$ cp symbolicatecrash /Users/bang/Desktop/Crash
4)执行如下命令,即可正确解析crash文件
./symbolicatecrash xxx.crash xxx.app.dSYM > test.txt
./symbolicatecrash DemoModel.crash CA3ACCD1-F63D-3A37-9773-82B155C02DA6.dSYM >crash2.txt

5)打开crash2.txt就可以看到符号化的崩溃日志了



2.通过友盟符号化设备的崩溃日志


如果出现bug的构建版本是在自己的电脑上打包的,那么直接打开终端输入黑色部分的代码就能定位到崩溃的代码位置;


如果出现bug的构建版本不是在自己电脑上打包的,那么需要找到对应的构建版本拷贝到自己项目中构建版本的目录中



转载于:https://my.oschina.net/u/2320280/blog/882304

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值