难以定位的Crash怎么修?

Crashlytics

最近知乎上有同学邀请我回答:通过第三方统计所搜集的错误信息应该如何准确的修复?,其实是指收集上来的一些信息不充分难以定位的crash如何处理?刚好之前曾在这块做过一些工作,有一些体会,因此简单回答了一下,同时也是自己的一个整理总结,免得时间长了很多东西都忘记了。

crash大家肯定都遇到过,也应该遇到过一些没有头绪修不下去的crash, 有些在困扰你很久之后被你搞定,有些只能尘封在那里,弃之不管。

修复crash最重要的是要找到root cause, 也就是产生这一问题的根本原因,然而很多时候大家经常头痛医头,脚痛医脚,因为这样看起来最轻松简单有效,但往往把隐患埋藏起来,下次如果再因为这个root cause导致一个很奇葩的问题,你也许压根就没法找到任何头绪,这就是典型的技术债务的一种。因此建议大家修crash 一定要尽量找到root cause, 实在找不到的话,如果问题不严重,宁愿不修;如果确定要修,也要在修复方案上注明TODO,写清楚这是一个workaround方案,也许今后有哪位高人能修掉它呢?

回到知乎上的那个问题,通过crash收集系统所收集到的一些crash,仅凭crash堆栈信息难以定位问题,自己测试也难以必现,甚至根本无法重现,这种情况应该怎么办呢?

我这里抛砖引玉,给出一些自己的建议:

  1. 首先要根据实际情况,设置一些的crash相关指标,比如整体的crash rate不要超过0.2%, 某个crash影响的人数与数量,不要超过预期值。是的,我的意思是crash未必一定要修复,理论上大部分的都是可以修复的,但往往投入的精力与回报不成比例,也许我们可以把精力放在其它地方。另外就Android系统这碎片化的程度,各种兼容性问题太多太奇葩,我曾负责过一个crash顽疾整理工作,发现影响人数1~2个的一些crash, 居然有超过4000种,尼玛我看都看不完,谈何一个个分析处理?

  2. 根据crash的严重程度、影响范围,把值得修的问题都列出来,根据优先级逐个处理,新出现的crash理论上是都需要修复的。

  3. 善用Google, 耐心找找,大部分的问题别人也应该出现过,也头痛过,可能最终的现象不一样,但也许能在一些问题里找到蛛丝马迹。

  4. 实在找不到的,也许是收集到的信息有限,可以补充收集更多信息,一些第三方crash收集分析平台,比如crashlytics,其实也支持上传Log, 在关键地方多打些Log, 尽量保存更多crash现场附近的信息,异常要处理好,经常是一些异常被不合理的吃掉了,导致问题被掩盖。

  5. 还是不行就换个同事看看,别觉得丢脸,很多时候未必是水平问题,人很容易陷入到自己的思路里出不来。

  6. 同事大牛都请教过了,还是没辙?二分大法好,看这个crash是哪个版本开始出现的,一点一点定位到具体版本,再一点一点定位到具体的change,这就要求持续集成与代码管理要做到位。我们有不少超级难搞的问题,就是这种方式解决的,这种比较适合有一定重现概率的问题,如果完全没头绪重现,也只能根据提交的change, 根据经验联想猜测其可能性了。

  7. 如果还不行,只能用神器了,我的微信公众号里有文章介绍 《Appsee: 为什么叫它神器?》 Appsee有个功能,可以直接查看每次crash之前用户都干了些啥,如果这还不能定位问题,有点说不过去吧。

很多时候即便知道了原因,也未必能修复,有时候真是系统或者环境的坑,有时候可以换个实现方式或设计避开它,总之crash要尽量先定位出原因,之后怎么处理大家就各想各招吧,尽量用一些优雅简洁的方式去处理它。

另外可以使用一些静态分析工具,提前发现代码中的各种隐患,比如Lint, Find Bugs等等,平时养成良好的编码习惯,模块之间不要牵连太多,充分解藕,规范异常处理、仔细考虑各种分支异常场景,不要偷懒,多打些Log,单元测试能做好就更好了(我的公众号里也有介绍单元测试的文章,大家可以参考)。这样一方面可以提前发现问题,另一方面也可以在问题出现时轻松定位。

最后想提一下,这种难以重现的顽疾,对测试与开发都是挑战,很多时候需要大家通力合作才能有好的结果,切忌互相推诿,毕竟大家的最终目标是一致的。

本文首发在我的微信公众号 Android程序员,主要关注Android最佳实践、经验分享,大家可以通过搜索公众号ID:AndroidTrending 来关注,也可以扫码关注。


扫码关注 Android程序员

推荐阅读更多精彩内容