您的位置:首页 > 其它

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

2016-08-09 00:00 435 查看
摘要: 调试程序-断点,Debug,崩溃日志分析,友盟崩溃日志

一.设置和查看断点

断点可以分为以下3种类型。

1. 文件行断点设置

添加断点->右键选择Edit Breakpoint





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

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

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



图中所示红色方框中的选项,可以让你指定那一种动作。默认的是Debugger Command。还有以下几种动作供选择,下面逐一介绍。

(1).AppleScript

它是苹果提供的一种脚本语言,用来执行一些预先指定的行为。选中该选项,将会出现如图所示的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的构建版本不是在自己电脑上打包的,那么需要找到对应的构建版本拷贝到自己项目中构建版本的目录中

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息