LuckyHu Blog

首页 产品 工作室

从QuincyKit的"性能问题"开始扯

05 Jan 2015

最近几个月的经历真是非常坎坷,回头写个2013-2014年终总结好好反思一下这两年的得失。

说说最近遇到的这个问题,到“新公司”后,这边让解决的第一个问题就是crashlog收集方面的问题,还好之前一直从事这方面的东西,看了一下目前的搞法,据说用的是友盟的方案,真心挫,基本上就传了一些简单的应用信息,然后就是用backtrace函数和backtrace_symbols函数,把(不知道是哪个线程)调用栈的函数地址和符号传了上来,没有各个线程的backtrace,没有image的信息,更别说什么寄存器信息,selector信息了.

我问领导为啥不用一些更通用的方案,不说后面做得多自动化,至少前面抓log得全一点吧,最好和Aplle系统抓得那个一样就好了,这样方便用symbolicate脚本还原。说是之前准备用QuincyKit,结果这边的一个工程师通过调研发现QuincyKit有性能问题,崩溃的时候会卡住个10几秒,用户体验太差。QuincyKit这么大个开源项目,还真没听说过有性能问题,我觉得可能是之前那哥们敷衍了事吧,于是自高奋勇把这个活接过来了。

这里我自己也是犯了些傻,首先看到原先的方案直接把backtrace_symbols的信息传上来了,就去问以前负责这块的这个哥们,难道你们不做symbolicate吗(我真心不是装逼,这个用中文说很奇怪),我估计他是直接利用版本号,用atos搞的,所以没懂我说的啥,就说不做,我一听,那这么整改bug还不全靠猜,因为xcode应该是把大部分的信息都strip掉了,我为了证明这个,还特意去看了linker的原理,想从理论上说明直接抓backtrace_symbols不靠谱,后来才发现自己想多了。

先自己建了个简单的项目,没发现集成了QuincyKit有啥问题,后来就把QuincyKit直接加到项目中,发现还真有卡死的情况出现,在4s上能夸张到30s左右,大概读了一下QuincyKit的源码,发现其实在抓取crasshlog的部分和QuincyKit一点关系没有,QuincyKit只是做了一些上层的封装,更底层的抓取都是用的PLCrashReporter,另一个开源项目。

本来类似的性能问题,最好的调试方法就是用Time Profile这样的工具,但公司不给配发布证书,没办法整,于是只能再搞来PLCrashReporter的源码,大概读了一下。于是猜测有可能有几个地方: 1.本身抓取的代码再次crash掉,所以造成递归的情况,这样系统可能会在认为你卡死主线程时间过长的情况下才把你干掉。 2.本身app进程所占用的资源太多,卡死是在回收系统资源造成的,crashlog的抓取其实很快。 3.plcrashreporter在初始化的时候会传入一个config参数,设置了几种方式,有两种方式会尝试直接把二进制文件中的符号表信息和oc的selector信息给还原出来,这个可能会很慢。 4.plcrashreporter在记录crash的时候,会把数据打包成一个pb格式的文件存到文件系统,所以有可能是这个格式转换太慢,或者是io太慢.

看了一下卡住的crashlog,没有发现1的情况,然后利用plcrashreporter的generateCrashError(大概)的方法,生成了一个crashlog但并不真正crash掉,发现依然很卡,排除2.然后3说的情况,在QuincyKit中使用的是PLCrashReporterSymbolicationStrategyAll这个选项,改成PLCrashReporterSymbolicationStrategyNone。

果然是3说的原因。所谓的性能问题解决了,其实是自己没搞懂就乱用。修改一行代码就解决了。

说一说这个配置的问题,他的作用是告诉plcrashreporter,是否需要在crash的时候去符号表中把相应函数地址对应的符号读出来,如果不用的话,那么它就把函数地址直接写在后面。那有什么意义呢,意义在于如果选择是的话,配合你在xcode中把strip symbols在Debug的时候给关掉,那么即便是调试的版本crash掉以后,也能看到很有用的crashlog的信息,对应的函数名都会有的,在公司开发(某些没有正规流程的公司…..)中还是很有用的,因为经常有测试人员会直接到你的电脑上来安装某个版本,但只要你再build一下,对应的dsym就不对了,那时就算崩溃了,也不能还原符号表。

关于为什么这个选项会导致慢得原因,我猜测和app的二进制文件的大小有关系,我在demo工程上没有任何的问题,因为demo工程的二进制文件只有几十k,而我们正式项目的二进制文件有90几M,所以会有这么大的差别。我觉得貌似是时候给源代码减减枝了。