一、前言
关于移动端的崩溃分析的必要性,我们知道移动端有以下特性,终端分布广,出问题后不易定位,日志收集需要额外处理,版本本更新,跟前端,后端比起来,周期会长很多,虽然也有相应的热更新手段,在苹果的审核机制面前,也只能认怂。种种条件对移动端软件质量的要求较高,同时还要求有远程收集日志并分析的能力。一般崩溃发生后,程序员的第一反应肯定是:在我这好好的,肯定不是我的问题,不信我拿日志来定位一下,于是千辛万苦找出用户日志,符号表,提取出崩溃堆栈,拿到了下面的结果:
addr2line-ipfCelibxxx.so007da904007da9db007d789500002605007dbdf1logging::Logging::~Logging() LINE: logging.cc:856logging::ErrLogging::~ErrLogging() LINE: logging..cc:993base::internal::XXXX::Free(int) LINE: scoped____.cc:54base::___Generic<int, base::internal::_____loseTraits>::_____sary() LINE: scoped_______.h:153base::___Generic<int, base::internal::_____loseTraits>::_____eric() LINE: scoped_______.h:90
如果是接入了某些崩溃分析平台,还能实时发出告警,你一点开就看到程序蹦在哪了,影响了多少用户等等,如下图
看了这个,恍然大悟,原来是这一行写的有问题。这是移动端的常用的崩溃分析过程,不管是开发哥哥人肉去看还是通过各种平台查看,那其中原理是什么呢?下面我们简单了解一下。
二、原理
我们了解原理前,先了解一下符号表是什么。 符号表是记录着地址或者混淆代码与源码的对应关系表。下面我们分别用一个小demo程序来讲解符号表及反解的过程。
2.1 iOS-OC、Android-SO符号化原理
a.示例源码:
intadd(){ inta=1; a++; intb=a+3; returnb; } intdiv(){ inta=1; a++; intb=a/0; //这里除0会引发崩溃returnb; } int_tmain(intargc, _TCHAR*argv[]){ add(); div(); return0; }
b.对应符号表,这里简化了符号表,没带行号信息
0x00F913B0~0x00F913F0add() 0x00F91410~0x00F91450div() 0x00F91A90~0x00F91ACD_tmain()
c.现有一崩溃堆栈
0x00F9143A0x00F91AB0
d.进行符号化
0x00F9143A0x00F91AB0
2.2 Android-Java 符号化原理
a.示例源码:
packagecom.aliyun.gts.testclassUser{ intcount; UserDTOuserDto; UserDTOget(intid){...} intset(UserDTOuserDto){...} } classUserDTO{ intid; Stringname; }
b.符号表
com.a.b.c.d->com.aliyun.gts.test.Userintcount->acom.aliyun.gts.test.UserDTO->bcom.aliyun.gts.test.UserDTOget(int) ->cintset(com.aliyun.gts.test.UserDTO) ->dcom.a.b.c.e->com.aliyun.gts.test.UserDTOintid->aStringname->b
c.现有一崩溃堆栈
com.a.b.c.d.d(com.a.b.c.e)
d.进行符号化
//符号化com.a.b.c.d.d(com.a.b.c.e) //查找com.a.b.c.d, 命中com.aliyun.gts.test.User//查找com.aliyun.gts.test.User.d 命中 set()//查找com.a.b.c.e,命中 com.aliyun.gts.test.UserDTO//符号化结果为com.aliyun.gts.test.User.set(com.aliyun.gts.test.UserDTO)
三、如何为自己的应用选择方案
可以分成以下四种方案:开发人肉分析、使用其他公司的开放平台、私有化部署、自建平台;
3.1 开发人肉分析
如果应用使用场景不高,或以选择由开发人肉进行分析,但是符号表的管理工作也会随着版本越来越多而增加,符号化的成本也因此会不断增加。
3.2 使用其他公司的开放平台
当前也有较多的公司提供崩溃分析服务,直接接入对应的SDK就可以,可以利用平台的能力进行快速的崩溃分析,平台的收费也各式各样,还有些是免费的服务,对于数据安全要求较低的产品,可以考虑此方案。
3.3 私有化部署
如果对数据安全要求较高,但是又没研发力量自己开发一套,可以考虑买一些公司的私有化部署方案,把整个服务部署在自己的集群里,可以保证数据安全,当然费用上会比直接使用公网的平台高许多,但也会比自建平台的成本低一些。
3.4 自建平台
如果公司自有Devops中台团队,且对数据安全要求较高,可以考虑自建崩溃分析平台,但在日志收集、符号解析、数据聚合等方面需要较多的精力去建设,需要考虑投入产出比的,最后还需要部署到自己的集群上,整体的成本是比较高的。
四、总结
本文从原理上简单描述了移动端崩溃分析,给移动端开发者一个思路与建议,开发者可以根据自己的应用场景,选择适合自己的崩溃分析方式。