TSC扫描与宕机堆栈匹配关联分析应用

发表于2015-10-23
评论0 3.5k浏览

一、 核心目标

通过建立TSC扫描结果与client宕机堆栈异常数据之间的关系,快速精准的通过扫描工具定位已导致外网crash的代码问题和原因。同时,衍生评估程序修复TSC扫描问题后,实际外网用户crash问题的改善情况。

二、 问题回顾

Ø  问题现场:三国之刃Clt

Ø  crash规模:导致4000 用户crash

Ø  问题原因:

RDMBUGLY上报crash堆栈信息,定位导致程序crash的错误代码段。

案例如下:

crash处的代码分析定位到是getControlLayer()函数空指针导致宕机。

接下来我们发现此问题TSC是能够准确扫描并报错其空指针问题的,如下图:

但为什么程序并没有根据TSC扫描结果提前预防呢?三国之刃此类多级指针的报错多达1.2w ,难以让开发商提前预防保护。

Ø  问题反思:

TSC工具发现的风险点众多时,亦或是crash堆栈的问题列表很长时,这两种无论从哪一方由程序入手排查,如此庞大数量级的工作量都会成为程序入手解决问题的瓶颈。

当然程序可以选择从无数的堆栈中,按照TOP的问题依次排查解决,里面也不乏充满了无法很快定位和解决的问题,此时筛选和第一步剔除冗余信息的快速定位就显得尤为重要了。

Ø  问题解决:

我们尝试将堆栈宕机与TSC扫描已出现的问题进行匹配,精确地定位出已经导致外网crash的风险点,首先解决了快速定位的问题。同时我们也另辟角度如何闭环化跟踪代码修复后的实际效果呢?如何评估用户修复TSC扫描问题后外网crash问题的改善情况呢?我们发现也可以用此堆栈和扫描问题的跟踪来排查效果,累积案例。

三、 自动分析方案设计

1.    前期条件

1)    需要项目每次Rdm/Bugly上传对应版本符号表,由项目测试经理推动。

2)    指定关注的Rdm/Bugly对应版本。

2.    方案流程

 

3.    获取rdmbugly数据

TSC接入Crash关联方案,只需进行一次项目配置,每天将自动同步外网rdm或者bugly数据。    

    

4.    按照类型过滤Crash问题

       针对C /C#不同项目类型,采用不同的过滤标准。

       C 项目我们聚焦空指针和越界类型错误,在RDM上错误类型通常为SIGSEGVSIGBUS.如图:

C#项目中,只需关注C#异常类型,而且在C#报错中有更详细的类型划分.如:OverflowException, IndexOutOfRangeExceptionNullReferenceException

5.    Crash堆栈分析:0/1

TSC空指针扫描为例,大致可以划分为两种:

第一种直接报在空指针解引用处,对应RDM报错Crash 0级堆栈信息,如图在文件MenuTalks.cs 函数OnMoveNext()中,代码第150行。   m_CurrentDialog2为空时发生空引用,0级堆栈对应RDM堆栈详细如下图:

第二种报错通常为多级调用,对应RDM报错Crash 1级堆栈信息。如图在文件MD5.cs 函数MD5(const char* szTesxt,int len)中,代码第29行。

szText为空时发生crash0级堆栈对应的是strlen所在函数,而1级堆栈才是对应的该报错所在的函数MD5()。 对应RDM堆栈详细如下图:

6.    TSC扫描问题,堆栈匹配

分析流程:堆栈分析Server—>获取TSC平台Issue—>匹配文件,报错,函数名等信息—>记录堆栈和问题关系—>TSC平台显示结果。

重点问题:编译器由于内部实现的不同而不同,内部实现包括对象在内存中的布局,继承的实现,虚函数调用处理等,所以导致他们的name mangling不是标准化的。很多项目Crash信息使用符号表还原后,表现的堆栈格式也不尽相同。

实际案例:

Ø  如三国之刃IOSRDM堆栈格式:

级别

无效

无效

::::函数(参数)(文件:行号换行符;

0

sgzr

0x03a58436

YiDou::YDTreasureNewPresenter::

onTiXingShow1(YiDou::YDEvent*)(YDTreasureNewPresenter.cpp:640);

Ø  欢乐斗牛AndriodRDM堆栈格式:

级别

无效

无效

无效

::::函数(参数)(文件:行号换行符n

#00

pc

0044d4d8

libNewHLDN.so

cocos2d::extension::CCTweenFunction::

circEaseInOut(float)(/data/rdm/projects

/8675/source/client/cocos2d-x-2.2.2/projects/NewHLDN/Game/Project/Android/../../..

/../../extensions/CocoStudio/Armature/utils/CCTweenFunction.cpp:301)

 

Ø  御剑2AndriodRDM堆栈格式:

级别

无效

无效

无效

_ZN numnum 函数(文件:行号) xx 换行符n

#00

pc

0010a282

libyujian.so

_ZN9Animation19getFrameModuleCountEi(/data/rdm/projects/7231/android/jni/../../

yujianonline/Animation/Animation.cpp:585) 0x0

这种Name_Manling格式解析详见https://en.wikipedia.org/wiki/Name_mangling

Ø  天天飞车(Unity项目)AndriodRDM堆栈格式:

C#报错无堆栈层级,默认自上而下分析,对应0级开始自增。

级别

.函数(参数)

StringUtility.UTF8BytesToString (System.Byte[]& str)

 

目前我们已经掌握了几种常见的堆栈格式解析,并且会根据新接入项目堆栈特征,自动适配类型,解析出文件名,行号,Crash函数等关键信息。然后,根据TSC扫描报错信息,报错文件,报错类型,报错函数等和堆栈信息匹配记录。结合后推荐适合项目优化修改的代码。

7.    TSC推荐结果修复,降低项目Crash

根据匹配结果,在TSC平台上,我们会根据Crash影响用户数量,分别对CrashTop10,50,100分层推荐,项目组可以根据周期人力,修复Crash关联上的报错。

程序可以在TSC平台打开关联报错,快速跳转到关联RdmCrash堆栈。

四、  项目效果和实际数据举证

在三国之刃项目4.2 版本(平均crash率是3.7%),按照上述方案进行匹配关联分析,并推荐Crash数量在100 空指针问题进行修复。程序修复这些问题后,在三国之刃5.0.0.29版本平均修复率下降到(0.87%)。在TSCRDMBugly)平台验证,这部分问题堆栈确实已无上报。

以下为三国之刃上报次数100 修复问题列表:

序号

RDM ID

上报次数

报错文件

行号

1

60369385 60370391 60325047

60368063 60367074

5473

YDAnimationPlayer.cpp

257

2

60368345

4352

YDHorseSkill.cpp

96

3

60369390 60368367

886

YDMiliBookUpgrateMainPresenter.cpp

149

4

60323036

493

YDHorseFeedMainPresenter.cpp

148

5

60323023

373

YDBeautySencePresenter.cpp

142

6

60368360 60368352 60370097

60367055

305

YDTreasureNewPresenter.cpp

223

7

60368350

298

YDCardActivePresenter.cpp

260

8

60322067

172

YDRankMainPresenter.cpp

207

9

60370372

164

YDCmcoat_MStonePresenter.cpp

162

运用同样的方案,我们对全民超神,六龙在天等客户端项目,各自选择一个版本进行分析。排除无法解析的堆栈后,对可识别的错误数据进行匹配,统计用户匹配数量和比例如下:

注:用户匹配比例=匹配用户总数/可识别用户总数(排除堆栈无法解析错误)

以全民超神项目为例,采用此匹配方案,在最优情况下,通过修复TSC推荐关联问题,可识别用户上报数量减少25.28%,可以减少271152个用户异常。

综上,未来我们可以从大量可疑误报中,提炼这部分Crash真实发生的空指针问题共性,从Unity类型错误,类成员空指针错误,函数返回直接解引用,多分支可能返回解引用等分类中,优化扫描粒度,从而更精准的在Crash发生前,提前发现预防。 

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引