状况:最近苹果发布iOS11 beta4,导致我们崩溃率上涨0.02%
crash.png因历史原因,Event未加工程前缀,Event为自定义类。从crash堆栈可以看出,crash很明显没找到对应方法名。可是工程里面确实有Event这个自定义的类,并且引入编译进去了工程。
那么问题来了,既然我们工程里面有Event这个自定义的类,为什么还是找不到方法呢。我们开始怀疑是和苹果本身提供是函数冲突了,那么这个函数到底是哪一个framework的呢?经过调试我们发现和photo.framework有关。使用安装了iOS11 beta4的真机调试,移除photo.framework就ok,加入就crash。那么我们基本确定是photo.framework。
但是问题又来了,photo.framework是以option引入到工程里面的,就是说只有include其里面的头文件才会加载photo.framework进入内存,并且framework都是打包期间就固定编译进IPA里面了,我们是用xcode8发的线上包,也就是说线上包的photo.framework是低版本的,因为bug在非iOS11 beta4的机器上是不存在的。并且我们也反汇编了打包机的xcode里面的photo.framework并没有发现Event这个类,这难道是苹果在iOS11 beta4动态修改了我们的photo.framework增加了Event的类,联想到dylib最近升级到dylib3,瞬间吓出一身冷汗,苹果是要逆天,不让别人使用动态更新,自己却来个更猛地,可是后来再想想这种可能性是很小的,应该是不可能。
既然photo.framework无Event类,那么就可能是photo.framework使用了其他是内部framework,才导致这个bug,顺着这个思路,我们惊喜的发现,Photos.frameworks调用了系统私有API frame work “/System/Library/PrivateFrameworks/Symptoms.framework/Frameworks/SymptomAnalytics.framework/SymptomAnalytics”
从这个路径我们可以看出这是与苹果系统相关的私有framework,猜测,不同iOS系统版本里面的私有framework是可能不同的,我们那个bug就刚刚好碰巧撞到枪口上了。找到了对应的问题framework,并且我们自定义的Event类后于系统framework编译进去
那么如何防御这种crash呢
1.类强制加前缀,并静态代码走查。
2.selector防护,类似与jspatch拦截消息转发的最后一步不让其崩溃。
3.推荐使用libextobjc里面的safecategory
备注:同事反馈后,苹果在beta 5已经修复
https://forums.developer.apple.com/thread/83555 ,
网友评论