码迷,mamicode.com
首页 > 其他好文 > 详细

关于Debug

时间:2015-04-29 14:51:38      阅读:117      评论:0      收藏:0      [点我收藏+]

标签:

在使用XCode使用过程中, 对已经释放了的对象发送消息时出现的崩溃较难定位.一种简便的方案是在Debug时定位该问题:

1. 在XCode的工具条上: Product -> Edit Scheme -> Diagnostics将Enable Zombie Objects选项勾上, 也可以使用在Arguments里面添加NSZombieEnable为yes的方案.

2. 在断点栏点击左下角的+号, 添加一个All Exception Breakpoint.

 

 

关于Crash:

 

Crash最多的有两种, 一种就是signal SIGABRT, 大概的意思就是发送Message出现问题, 信号迷失了. 这种的Crash其实是很好定位,Crash了后直接看Console里出的最后日志. 比如这段:

2012-03-28 19:26:33.055 TableViewMenuDemo[3916:f803] *** Terminating app due to uncaught exception ‘NSInvalidArgumentException’, reason: ‘-[__NSArrayI replaceObjectAtIndex:withObject:]: unrecognized selector sent to instance 0x6a3f3d0′

*** First throw call stack:

 

找到reason字段, 那就是原因, 说NSArray调用replaceObjectAtIndex:withObject:

这个方法是NSMutableArry的, NSArray并没有该方法, 信号迷失掉了, 所以Crash了. 0x6a3f3d0 是出问题的内存地址, 查下内存地址或搜下调用方法就比较好定位了。

 

 

XCode4上还有个更好用的定位方法,就是设置一个Exception Breakpoint.

 

在工程的左边栏中选择Breakpoint Navigator, 点击下面的+号添加一个Exception Breakpoint, 然后再运行试试, Crash后, 就直接定位到了那行代码了. 再根据Console里的日志进行定位修改就好了.

 

下面说说另一种Crash, EXC_BAD_ACCESS, 这个比较头疼, 因为Crash的时候, 可能是之前的某个变量被释放了, 现在访问该变量时出问题. Console里也没显示什么日志.

 

这里光加入Exception Breakpoint是不够的了, 打开Scheme选项选择Edit Scheme. 然后勾上Enable Zombie Objects和Malloc Stack那两项, 记住一般只有在定位EXC_BAD_ACCESS时候才勾选, 别有事没事都勾上.

 

这样重新跑一下, 如果是到Exception Breakpoint处停止了, 可以在Console中输入: c(continue)按回车继续跑, 直到Crash. 看下Console是不是有跟SIGABRT类似的错误信息日志了, 后面定位什么的你懂的.

 

如果还没有日志, 在Console中输入po$eax$eax标志出错的地方,适用模拟器,真机用$r0(话说EXC_BAD_ACCESS这种错误模拟器定位就行),还可以输入比如:po[$eaxname]po[$eaxreason]等指令查看错误其他信息(注意方括号后没分号的). 然后, 就没有然后了.

 

还要补充点, 程序开发过程就要多关注左边栏中Issue Navigator里的警告信息,XCode不仅会警告, 还多数给出解决建议, 能避免后面不必要的Crash.

 

如果程序Crash, 第一时间关注下debug Navigator里的执行信息,将滑块拉向右边可以看到更多调用信息,根据这个能大致设想是调用什么方法或进行什么操作时Crash的.

 

 

通过NSZombieEnabled环境变量,我们可以很多Bug了。但有时错误发生在framework内部,这时断点的当前栈并不在我们的代码当中。比如:

xxx: *** -[CALayer release]: message sent to deallocated instance 0x1e140270

这个CALayer并不是我们直接创建,而且release消息也不发生在我们的代码中。我们完全不知道这个CALayer是那个View的。所以就没法明确那个类出现问题。如果知道这个CALayer在什么地方alloc的就好了,这时我们就需要 MallocStackLoggingNoCompact环境变量了。这个环境变量开启的alloc日志,它会记录每个对象alloc时的栈的情况。根据栈的情况我们就可以弄清楚那个类初始化了这个Layer,从而检查代码解决问题。设置方法和NSZombieEnabled类似。

 

当message sent to deallocated instance消息产生时,在调试终端输入:

info malloc-history 0x1e140270

就会打印layer alloc时栈的情况,可以看到代码调用情况,找到我们自己的代码,检查代码并修改吧。

关于Debug

标签:

原文地址:http://www.cnblogs.com/xiaxianbing/p/4465914.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!