阿里技术 2024年10月25日
NativeCrash率从万分位降到十万分位,我做了这几件事...
index_new5.html
../../../zaker_core/zaker_tpl_static/wap/tpl_guoji1.html

 

饿了么商家版APP针对Native Crash问题展开专项治理,通过分析成因、进行准备工作、整体异常分析及案例解决,成功将Native Crash率降至历史低位,提升了用户体验和软件稳定性。

饿了么商家版APP的Native Crash问题较为棘手,其成因包括jni内部问题、多线程竞争、Android ART异常等。了解异常的信号量及信号Code码有助于加快排查方向。

治理工作中使用EMAS平台收集和分析Crash异常堆栈信息,同时结合UC LogAnalyzer分析工具协助排查问题,提升处理效率。

通过对多个异常案例的分析和解决,如libart.so异常、libjsi.so异常、arm-v7a OOM异常、多开环境异常等,成功降低了Native Crash率。

最终团队将App的Native Crash率优化至仅0.007%,获得用户好评,后续将持续关注并优化产品性能。

原创 郑丹 2024-10-25 08:31 浙江

饿了么商家版APP通过专项治理行动,成功将NativeCrash率从万6降至十万分之六,显著提升了用户体验和软件稳定性。



这是2024年的第81篇文章

( 本文阅读时间:15分钟 )




01



背景

App开发过程中,崩溃率是衡量App稳定性的关键指标。因为App崩溃不仅仅影响用户的即时体验,更对用户留存率构成了潜在的威胁。它如同一颗隐形的定时炸弹,随时可能引发用户体验的灾难。App崩溃分为Java Crash和Native Crash 2种。


Native Crash因为其上下文信息不完整、错误提示模糊以及难以捕捉等特性,相比较Java Crash,定位及修复更为棘手困难。作为外卖商家日常运营不可或缺的助手,饿了么商家版APP的用户体验一直是我们团队的首要考量。然而,伴随着业务迭代与设备系统的不断升级,我们的应用Native Crash率上升明显,一度从原先的万2攀升到了万6以上。为此我们启动了Native Crash的专项治理行动,致力于为用户提供一个更加可靠稳定及高效的App应用,让所有商家都能享受到无忧的数字化运营体验。




(治理前crash趋势表)



02



Native Crash 成因及描述说明




为了更好的治理Native Crash,先来了解下Native Crash 的成因。从上图可以看到,发生在Java层的Crash称为Java Crash,该Crash异常日志有具体的堆栈信息可以查看分析,修复相对明确具体。发生在Native层的Crash称为 Native Crash,由于大多该类型crash堆栈信息模糊,导致定位耗时,成效低。


常见导致Native Crash的原因有如下几种类型:


1. jni内部数组越界、缓冲区溢出、空指针、野指针等;

2. jni中多线程出现竞争,比如一个线程调用jni接口释放了内部一个指针,另一个线程调用另外一个jni接口还在使用这个指针;

3. Android ART发现或出现异常;

4. 其他framework、Kernel或硬件bug。


但是在Native Crash上报异常日志中均会包含异常的信号量及信号Code码,故了解信号量及信号Code有助于我们加快确定排查方向。




信号量

信号Code

描述



SIGSEGV

SEGV_MAPERR

地址不在 /proc/self/maps 映射中,很可能是JNI中空指针的问题

SEGV_ACCERR

没有访问权限

SEGV_MTESERR

MTE特有类型

SIGABRT


程序主动退出,常见调用函数abort(),raise()等









SIGILL

ILL_ILLOPC

非法操作码(opcode)

ILL_ILLOPN

非法操作数(operand)

ILL_ILLADR

非法寻址

ILL_ILLTRP

非法trap,如_builtintrap()主动崩溃

ILL_PRVOPC

非法特权操作码(privileged opcode)

ILL_PRVREG

非法特权寄存器(privileged register)

ILL_COPROC

协处理器错误

ILL_BADSTK

内部堆栈错误



SIGBUS

BUS_ADRALN

访问地址未对齐

BUS_ADRERR

访问不存在的物理地址

BUS_OBJERR

特定对象的硬件错误











SIGFPE

FPE_INTDIV

整数除以0

FPE_INTOVF

整数溢出

FPE_FLTDIV

浮点数除以0

FPE_FLTOVF

浮点数上溢(overflow)

FPE_FLTUND

浮点数下溢(underflow)

FPE_FLTRES

浮点数结果不精确

FPE_FLTINV

无效的浮点运算

FPE_FLTSUB

越界

(异常描述表)



03



准备工作

当前我们使用的crash收集平台和阿里集团一致,都使用EMAS平台来收集和分析应用的 Crash 异常堆栈信息,该平台功能和市面上常用的友盟、bugly等应用监控平台功能类似,提供crash数量、关键异常信息及异常堆栈内容等。同时结合UC LogAnalyzer 分析工具(主要作用分析UC webview相关异常) 来协助排查问题提升处理效率。






04



APP异常整体分析

为了更好的分析 Native Crash,我们以2024年度某个时间点top crash聚合数据为例来展开分析。



针对上述top crash特征分析提取内容如下:


crash类型

数量

设备特征

libart.so

1858


libart.so (_ZN3artL38Executable_getMethodReturnTypeInternalEP7_JNIEnvP8_jobject+52)

1475



libjsi.so

1409



ligGLES_mali.so

2081




05



案例Case说明

5.1 libart.so 异常

在分析top1 libart.so问题时,解析相关日志发现问题大多发生在APP初始化阶段。以某个crash日志为例,发生问题的进程id=24657,线程id=17891。







查看日志中与线程活动相关的记录,注意到tag为“XMPush-24657”的异常日志,初步判断可能为小米推送服务初始化异常导致。从前面该异常特征分析看99%以上都集中在小米和红米设备上,和小米推送刚好能关联上。但是分析小米推送jar包代码及和集团多个采用相同版本小米推送服务的团队交流确认,他们并未遇到类似问题。和小米技术同学对接,对方也未接收到该版本异常反馈。故先暂时否定小米推送引发异常问题推论。


为了获取更多信息,只能再次分析日志。捞取数十份日志后,在某个日志中发现发生异常时主线程信息。





经深入探究,发现App启动过程中某个特定场景需要在初始化阶段启动一个独立线程对SharePreferences文件处理后存储操作,而该处理过程存在潜在风险,可能诱发不可预期的崩溃问题。因此尝试在灰度版本改用文件来处理。新版本上线后该crash清零。

5.2 libjsi.so 异常



从日志上看crash信号量为 SIGSEGV,code = SEGV_MAPPER 。从前面章节的异常描述表中可知 SEGV_MAPPER 异常为空指针异常。翻看日志找到发生异常的调用链堆栈如下。


jsValue = callbackFunction.call(jsContext, null, returnJSValue);


从上面代码分析如果异常确实是空指针造成,那么就有2种可能:


其中 异常的 libjsi.so 由外部三方提供,遵循优先排查自身可控因素的原则,我们先来排查调用方法的三个参数,jsContext 成了引发问题的最大疑点。为了验证这一假设,我们将 jsContext = null 强制赋值作为参数进行验证,复现了该异常,其中异常堆栈和错误信息与用户上报的内容吻合。确定了原因后通过对参数判空来解决。

// 如果被回收了就不执行if (jsContext != null && jsContext.isDisposed()) {return null;}jsValue = callbackFunction.call(jsContext, null, returnJSValue);

5.3 arm-v7a OOM 异常




上述日志显示在分配内存时发生异常 ( Adreno-GSL: <gsl_memory_alloc_pure:2955>: ERROR: kgsl_sharedmem_alloc() failed! Allocation size: (10200 KB); Flags: (0x100000) ),out of memory 了。同时结合查看发生异常的设备特征均为32位so (CPU型号: armeabi-v7a)




推断低版本设备在申请分配内存时异常,参考《阿里开源 Patrons:大型 32 位 Android 应用稳定性提升 50% 的“黑科技”》文章引入 Patrons 库来解决提升低端设备性能。

5.4 #00 pc 0xda58 [anon:.bss]

异常报错不局限于上述的 anon:.bss,也可能是 libwebviewuc.so 或者关联了其他 so 报错。但是日志中有下面特征:






 

或者搜索异常日志,可以发现[anon:.bss]日志下真实包名前面为多开软件的包名信息:



根据上述 app 包名查询了解到我们应用的启动源于多开软件的使用,通过回访部分用户确认是在该时间点通过多开软件打开了相关的app,但是用户并未感知到崩溃异常。初步判断,在多开环境下,应用在初始化阶段可能遭遇了某些异常情况,导致崩溃并上报异常。同时多开环境自动重启应用,从而使得用户未感知到崩溃现象,只觉得是打开变慢了。


针对多开异常,我们考虑两种解决方案思路:


一是app初始化时检测是否处于多开环境,如果是则限制应用初始化。如何检测线上已有对应方式;

二是将多开环境下的崩溃问题作为普通崩溃异常解决。从用户体验和业务安全的角度考虑,允许用户合理多开是更优的选择。


然而,鉴于多开环境的复杂性和多样性,全面解决这一问题将需要投入大量的人力资源。鉴于当前此类崩溃事件数量较少,占比较低(1%以下),我们的策略是暂时保持观察状态,持续监控该异常情况,以便在必要时采取进一步行动。



06



结果

最终通过团队成员的通力合作,我们成功地将App的Native Crash率优化至历史低位——仅0.007%。这个结果不仅提升了app的稳定性,更获得了用户的一致好评与积极反馈。我们后续将持续关注并进一步优化产品性能,为用户提供更加稳定、流畅的应用体验。




(治理后crash趋势表)

参考链接

[01] 《阿里开源 Patrons:大型 32 位 Android 应用稳定性提升 50% 的“黑科技”》

https://www.infoq.cn/article/bvbf3iwjztvem4szamvw

[02] 《android多开原理和检测》

https://blog.csdn.net/c_kongfei/article/details/119914810




欢迎留言一起参与讨论~

跳转微信打开

Fish AI Reader

Fish AI Reader

AI辅助创作,多种专业模板,深度分析,高质量内容生成。从观点提取到深度思考,FishAI为您提供全方位的创作支持。新版本引入自定义参数,让您的创作更加个性化和精准。

FishAI

FishAI

鱼阅,AI 时代的下一个智能信息助手,助你摆脱信息焦虑

联系邮箱 441953276@qq.com

相关标签

饿了么商家版 Native Crash 异常分析 软件稳定性
相关文章