文档章节

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

HelloSwift
 HelloSwift
发布于 2016/08/09 15:57
字数 2862
阅读 259
收藏 1

一.设置和查看断点

断点可以分为以下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的构建版本不是在自己电脑上打包的,那么需要找到对应的构建版本拷贝到自己项目中构建版本的目录中

 

© 著作权归作者所有

共有 人打赏支持
HelloSwift
粉丝 0
博文 56
码字总数 42710
作品 0
丰台
程序员
iOS崩溃crash大解析//http://www.cnblogs.com/leixu/articles/5395340.html

iOS崩溃crash大解析//http://www.cnblogs.com/leixu/articles/5395340.html 前言 iOS崩溃是让iOS开发人员比较头痛的事情,app崩溃了,说明代码写的有问题,这时如何快速定位到崩溃的地方很重...

Youth_关旋
2016/11/08
24
0
Umeng Crash Symbolicator

一键把友盟iOS崩溃日志里的?????转成可见的symbol。 友盟的iOS应用错误分析工具收集到的崩溃日志(Stack Trace),有些情况下无法显示出正确的symbol,显示为一堆问号?????。 使用此工具可以...

红薯
2014/03/25
955
0
dwarfdump解析线上崩溃日志dSYM文件

1、dSYM文件:iOS构建时产生的符号表,它是内存地址与函数名,文件名,行号的映射表;iOS应用crash时也有堆栈,release版的应用,crash时的堆栈信息,全是二进制的地址信息;iOS平台中,dSYM文...

奋斗的青春年华
08/22
0
0
iOS-崩溃调试

在iOS开发调试过程中以及上线之后,程序经常会出现崩溃的问题。简单的崩溃还好说,复杂的崩溃就需要我们通过解析Crash文件来分析了,解析Crash文件在iOS开发中是比较常见的。 获取崩溃信息 ...

hfzhangzhang
2016/01/21
23
0
libc++abi.dylib: terminate_handler unexpectedly错误

今天测试app时发现一个必现的异常,当在登录成功后再打开登录前点击的页面时,就会在Xcode console中打印如下日志: NSScanner:nil string argument NSScanner:nil string argument libc++ab...

yoyoso
2015/03/09
19.3K
4

没有更多内容

加载失败,请刷新页面

加载更多

[Hive]JsonSerde使用指南

注意: 重要的是每行必须是一个完整的JSON,一个JSON不能跨越多行,也就是说,serde不会对多行的Json有效。 因为这是由Hadoop处理文件的工作方式决定,文件必须是可拆分的,例如,Hadoop将在...

Mr_yul
10分钟前
0
0
54:mysql修改密码|连接mysql|mysql常用命令

1、mysql修改密码: root用户时mysql的超级管理员,默认mysql的密码是空的,直接可以连接上去的,不过这样不安全; 注释:为了方便的使用mysql,需要把mysql加入到环境变量里; #后续自己输入mys...

芬野de博客
17分钟前
0
0
鼠标单击复制粘贴标签中的内容

<span ref="spanContentOne" id="spanContentOne" style="font-size: 14px;">或许不是最亮眼,总比瞎买强一点</span><!--<input type="button" @click="copyClick('1')" value="复制" />-......

帝子兮
21分钟前
0
0
使用axel多线程疯狂下载

在Linux中比较常见见的下载工具是curl和wget,但是下载比较大的文件两者都不支持多线程, 断点续传的作用不见得能发挥到最大。今天介绍一个axel工具,开启多线程疯狂下载。 安装 Fedora/Cen...

linuxprobe16
23分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部