研究线上bug,bugly地址:https://bugly.qq.com/v2/crash-reporting/crashes/e4cca56be9/520445?pid=2
又是潦草的一天,遇到问题没有先猜想(思考)上来就干,最后细节的东西了解了一大堆,毫无作用,到了晚上又过了一遍bugly的流程,5s解决问题,哈哈,我TM有点想笑,一整天干了个蛇啊!下面亲身记录下今天这一天,真TM牛X。
早上来到公司,包哥抛给一个线上bug,说了一大堆我也没听,核心就是你看看这是什么造成的,去解决了。我当然也是义无反顾,拿过来就干,先看下bug是什么样的:
这TM的,关键APP部分搞了一个16进制地址,这我怎么知道是怎么回事呢?我当时的想法就是把这个地方利用符号表符号化出来,然后再定位具体代码,心里还暗自咒骂bugly解析了个P,只能解析出库中的符号。
没办法,先符号化这个地址吧。因为我们开发完以后会把APP对应版本的符号表上传到Bugly上,所以我的想法就是先去将其下载下来,但事与愿违,bugly一但上传以后就会被压缩,我这里根本就下载不下来,心烦,到底能不能下载下来呢?带着这个疑问,打开了熟悉的”度娘“,输入关键字:”如何下载bugly上传的符号表“,结果一大堆上传文章,毫无下载的字样,后来翻看了一篇文章,一哥们说可以用bugly中的”符号表工具“,地址:https://bugly.qq.com/v2/downloads,如下图:
我以为利用它可以得到我的符号表,结果就是个p,这就是上传符号表的,墨迹了半天,浪费时间,未果。
接着我又注意到,bugly上有符号表的UUID的值,然后我们打的包虽然我不知道是第几个了,但可以比对,所以我找到了jenkins,从上面下载了符号表,利用我的工具https://github.com/UCliwenbin/IOS-CrashAnalysis对比了下,我草,一致,ok,符号表算是找到了。下面就是将这个地址转换为符号就OK了,我突然想到了之前用过的一个工具,叫”DSYMTool“,如何使用,看这篇文章:如何处理iOS崩溃crash大解析。完事具备,打开”DSYMTool“,发现里面实际使用的是**.xcarchive文件,我去,这不白折腾嘛。还好jenkins上有生成,OK,将其拖入,终于可以解析了。
然而,又是坑,解析的根本就不对,这不是扯犊子嘛!!兜兜转转一圈又一圈,刚踩一坑又一坑。这个时候,bug根本没解决,折腾了半天符号表,我TM的,好气,浪费时间,竟打擦边球。
这条路是断了,等于一上午毛也没干。到底是什么原因呢?再次回到bugly,因为块儿代码之前就出现过bug,因为这是个图片浏览器,需要访问大量的图片,所以,我怀疑可能是因为内存爆满,然后被杀死了,我带着我的困惑,看看bugly上用户的内存有多大,如下图:
只剩下1%啦?我嚓,这很有可能啊,然后我带着这个发现暗自窃喜,终于找到原因了。然后,我看到了图片调用的类,是这个类:PHFetchResult,然后我点进去后发现,文档中有这么个注释:
果然会因为内存不足的时候释放掉缓存中的数据。我深信不疑自己找到了问题的答案。到这个时候,我都看了哪些文档呢?我列一列:
- 如何处理iOS崩溃crash大解析
- Mac/iOS crash或者地址符号解析——工具篇
- Crasher工具的使用
- IOS中的内存不足警告处理(译)
- 解析iOS内存不足时的警告以及处理过程
- iOS内存警告问题解决
- PHFetchResult详解
然后我注意到:因为PHFetchResult是实现的一个数组,又提供了这么多的enum…xxx方法,所以我猜测遍历的时候是不是得用这些?所以我又看了下面的这些文章:
所以:我的解决方案是替换掉原来的for循环,利用enum…这个来替换。为什么这么做,因为bugly上是这么提示的:
喵的,这不是数组越界嘛,一定是for在遍历数组的时候,数组中的内容被删了,然后导致数组越界了。看似很合理,但我始终有一点不妥,因为我按照上面的博客写了个demo,发现for循环的过程中删除数组中的元素并不会奔溃。我将信将疑啊,关键是偶现bug,很难测试到,就这样吧,我觉得可以了。
心里总觉得不对,因为没有实际测试出这个问题,然后替换这个也不一定能解决这个问题。
不行,我还得看看bugly,此时已经是下午6点了。一天解决一个bug,还不知道是不是解决了,这很nice。我翻看着bugly,翻看着用户的操作,因为我想尝试着去还原下现场,下面看看用户是怎么操作的:
看着看着,突然发现,原来用户是操作到这一步奔溃的,那我也试试呗,突然发现确实有问题,然后我又回看了下奔溃日志:
这回我把注意力放到了红框这里(虽然它是系统调用)。突然间,我明白了,我感觉我彻底明白了,这不就是tableView在展示的时候,调用了我们APP中的代理吗?会是谁呢?那一定是cellForRowAtIndexPath在加载数据源的时候出的问题,然后我看了下代码:
这代码是TM谁写的,站出来,我保证不打死你,这真是一点防护都没有啊,果然有奔溃呀。
真是兜兜转转,最后5秒钟解决问题,浪费了一天的时间,想笑哈,摸鱼摸的真实。虽然浪费了一天时间,但我也总结了一些经验:
第一、要勤思考,遇到问题不要想当然的上来就做,我们应该先观察、猜想,思考为什么会出这个问题。在解决问题前对这个问题想的越明白,越透彻,到做的时候我们走的弯路就会越少。
第二、在查看bug的时候,如果对出问题的地方有详细的说明那最好,如果没有的话我们也应该观察其上下文,哪怕它是系统函数。只有把上下文搞清楚了,我们才能更加明白问题的本质。
第三、对一个问题,自己首先要把条理整理清楚,可以按照为什么会出现这个问题,怎么解决这个问题,然后验证确实是这个原因。如果自己连自己的说服不了,或者不合理,那一定是你错了。
算了,就写这么多吧,说的越多问题越多。虽然有点蠢,但我想把它写下来,以此为戒,以后不能再犯这种错误了,也希望能提醒其他在开发路上的小朋友们,希望对你们有用,能在我的错误中,学习一些经验,少走一些弯路。