昨天,运维的同事反馈说线上的App在某个账号身上发生了多次的崩溃,需要我排查一下原因.
因为公司的机制比较奇葩,没有使用第三方的Bug跟踪框架处理崩溃,导致唯一在我手上的bug信息就是后台运维提供的崩溃日志,以及手机信息和账号信息.
其实我一直以来都不是特别会处理这种bug,更何况只有一堆堆栈信息.
slide: db0000 crashTime: 2019-06-05 15:27:40 Exception reason: +[NSMethodSignature signatureWithObjCTypes:]: type signature is empty.
Exception name: NSInvalidArgumentException
Exception stack:(
0 CoreFoundation 0x00000002245d9294 <redacted> + 252,
1 libobjc.A.dylib 0x00000002237b39f8 objc_exception_throw + 56,
2 CoreFoundation 0x00000002244cee88 <redacted> + 1268,
...
后面的还有很多信息,但是关键的就是这一些了.
关键是这个[NSMethodSignature signatureWithObjCTypes:]: type signature is empty.
根据之前看的资料和查阅的资料看,简单看就是对象在发送消息的时候,其类型为空导致了崩溃.
道理我都懂,但是在茫茫的代码中去找一个这样的空对象谈何容易?
于是乎,我就是死马当活马医的想法,先去官网的App分析中去看看.
进入后我们选择需要查看的App然后点这个崩溃:
点击后我们可以看到崩溃的详细:
至此,我基本得到了结论,那就是在我的App正式版本1.2.1中,6月7日发生了崩溃,而且苹果也记录下了此次崩溃,这样就好说了.接下来我们就需要通过Xcode尝试去还原一下犯罪现场,不对是Bug现场.
先通过git工具checkout一份当时的代码,为什么要一份当时的代码,我们往后走就知道了.
先在菜单中选择Window
对应App以及对应的版本下载崩溃日志
果其不然,要崩溃日志下载下来,最后一步还原现场:
点击崩溃的地方,系统会提示打开对于的工程去崩溃发生的位置:
最后我们达到现场:
最后,其实这个是一个使用第三方NullSafe.m文件导致的崩溃,其实这个Bug比较尴尬,因为在我接手这个项目前,项目中一直使用这个文件,主要是处理NSNull的情况.
于是我跑去github上看看情况:
我使用的1.3.4的release版本,而现在这个类已经到2.0了而且有很大的改动.
作者的一句话引起了我的注意:
大概意思就是说,随着iOS版本的升级,会导致崩溃.
我会看了运维提供的手机与版本信息,6plus iOS12.3.1,因此我怀疑就是这个类在作怪,一次崩溃的分析也找到了答案.
但是问题是我如何去移除这个使用已久的类而不改变代码的健壮性呢?