iOS-野指针定位

本文详细探讨了iOS开发中的野指针问题,包括其定义、原因和定位难点。通过分析,提出了解决野指针异常的两种主要方法:内存填充和对象转发。并介绍了如何利用转发机制和消息发送的原理来实现防野指针策略,同时分享了代码实现和疑难问题的探讨。

原文地址

野指针

当所指向的对象被释放或者收回,但是对该指针没有作任何的修改,以至于该指针仍旧指向已经回收的内存地址,此情况下该指针便称野指针

野指针异常堪称crash界的半壁江山,相比起NSException而言,野指针有这么两个特点:

  • 随机性强

    尽管大公司已经有各种单元、行为、自动化以及人工化测试,尽量的去模拟用户的使用场景,但野指针异常总是能巧妙的避开测试,在线上大发神威。原因绝不仅仅在于测试无法覆盖所有的使用场景

    造成野指针是多样化的:首先内存被释放后不代表内存会立刻被覆写或者数据受到破坏,这时候访问这块内存也不一定会出错。其次,多线程技术带来了复杂的应用运行环境,在这个环境下,未加保护的数据可能是致命的。此外,设计不够严谨的代码同样也是造成野指针异常的重要原因之一

  • 难以定位

    NSException是高抽象层级上的封装,这意味着它可以提供更多的错误信息给我们参考。而野指针几乎出自于C语言层面,往往我们能获得的只有系统栈信息,单单是定位错误代码位置已经很难了,更不要说去重现修复

定位

解决野指针最大的难点在于定位。通常线上出现了crash需要修复时,开发者最重要的一个步骤是重现crash。而上文提到了野指针的两个特性会阻碍我们定位问题,对于这两个特性,确实也能做一些对应的处理来降低它们的干扰性:

  • 采集辅助信息

    辅助信息包括设备信息、用户行为等信息,往往可以用来重现问题。比如用户行为可以形成用户使用路径,从而重现用户使用场景。而在发生crash时,采集当前页面信息,配合用户使用路径可以快速的定位到问题发生的大概位置。经过验证,辅助信息确实有效的减少了系统栈对于问题重现的干扰

  • 提高野指针崩溃率

    由于野指针不一定会发生崩溃这一特性,即便我们通过堆栈信息辅助信息确定了大致范围,不代表我们能顺利的重现crash。一个优秀的野指针崩溃可以造成一天开发,三天debug,假如野指针的崩溃不是随机的,那么问题就简单的多

    Xcode提供了Malloc Scribble对已释放内存进行数据填充,从而保证野指针访问是必然崩溃的。另外,Bugly借鉴这一原理,通过修改free函数,对已释放对象进行非法数据填充,也有效的提高了野指针的崩溃率

  • Zombie Objects

    Zombie Objects是一种完全不同的野指针调试机制,将释放的对象标记为Zombie对象,再次给Zombie对象发送消息时,发生crash并且输出相关的调用信息。这套机制同时定位了发生crash的类对象以及有相对清晰的调用栈

解决方案

整理一下上述的内容,可以看到目前存在辅助信息+对象内存填充以及Zombie Objects这两种主要的应对方式。拿前者来说,填充已释放对象的内存风险

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值