iOS调试BAD_ACCESS错误、定位崩溃的位置

在iOS开发过程中经常会遇到野指针和僵尸对象的问题,比如访问已经释放对象的成员变量或者发消息即会出现BAD_ACCESS错误,这类错误往往在控制台中不能很直观的看到错误的具体位置和信息,以下几种方法可以帮助我们快速的定位到错误的位置并及时修复:

1.通过 Zombie

如果打开了ARC或垃圾回收模式,在程序中发消息给已经释放的对象,将会引起程序崩溃。这时定位崩溃原因将非常困难,因为出问题的对象已经重新分配了。【MRC下对release的对象再访问;不支持ARC对象(CGImageRef)release之后再访问】解决方法:可以通过启动僵尸对象(Zombie Objects)来解决,开启该选项后,程序在运行时,如果访问了已经释放的对象,则会给出较准确的定位信息,可以帮助确定问题所在。
功能的原理:在对象释放(retainCount 为0)时,使用一个内置的Zombie对象,替代原对象。
第一步:设置僵尸对象:


566737-87f2d6dd2918c326.png

2.png

第二步:打开Instrument


1.png

第三步:选择Zombies
2.png

第四步:点击运行
3.png

然后出现就会看到如下画面:
4.png

点击你的模拟器要出现问题的地方,重现错误,返回到Instruments中,按照下图操作:


5.png

点了箭头之后,会有变灰色的行出现,这个就是出问题的地方,双击这一行进去,就可以定位到我们出问题的地方了:
6.png

2.Xcode 7 已经集成了BAD_ACCESS捕获功能:Address Sanitizer。 用法如下:在配置中勾选?Enable Address Sanitizer

AddressSanitizer的原理:当程序创建变量分配一段内存时,将此内存后面的一段内存也冻结住,标识为中毒内存。AddressSanitizer比Zombie拥有更强大的捕获能力,特别是在malloc对象和内存越界方面。【在Build Settings中的Custom Compiler Flags下为other C Flags添加-fsanitize=undefined-trap -fsanitize-undefined-trap-on-error】

6.png

3. 设置全局断点快速定位问题代码所在行:

3.png

4.png

5.png

4. 重写object的respondsToSelector方法,现实出现EXEC_BAD_ACCESS前访问的最后一个object。

有时程序崩溃根本不知错误发生在什么地方。 比如程序出现EXEC_BAD_ACCESS的时候,虽然大部分情况使用设定 NSZombieEnabled环境变量可以帮助你找到问题的所在,但少数情况下,即使设定了NSZombieEnabled环境变量,还是不知道程序崩 溃在什么地方。 那么就需要使用下列代码进行帮助了:

#ifdef _FOR_DEBUG_
-(BOOL) respondsToSelector:(SEL)aSelector {
        printf("SELECTOR: %s\n", [NSStringFromSelector(aSelector)      UTF8String]);
        return [super respondsToSelector:aSelector];}
#endif

你需要在每个object的.m或者.mm文件中加入上面代码,并且在 other c flags中加入-D FOR_DEBUG(记住请只在Debug Configuration下加入此标记)。 这样当你程序崩溃时,Xcode的console上就会准确地记录了最后运行的object的方法。

你可能感兴趣的:(iOS调试BAD_ACCESS错误、定位崩溃的位置)