闪退、崩溃、无响应、重启等是应用稳定性常见的问题现象,稳定性故障大体可归类为ANR/冻屏、Crash/Tombstone、资源泄露三大类。软件绿色联盟联合华为终端开放实验室,通过系列文章对三类故障的产生原因、故障现象、触发机制及如何定位等,展开深度解读。
本期将详解ANR类故障,并通过一个Binder阻塞问题案例,向广大读者演示如何有效定位ANR类故障。
1、ANR问题原因分析
华为终端开放实验室技术专家结合丰富的开发、测试、故障分析经验,对ANR问题产生原因、现象、故障检测做了提炼与归纳,方便开发者更好了解ANR相关内容。
2、ANR问题定位方法
1)打开system_app_anr@XXXX文件,查看ANR发生进程、进程号、主线程状态,是不是有明显的死锁或者明显binder调用阻塞;
2)如果是死锁,看业务代码即可;
3)如果是binder阻塞,查看binder调用链信息,查找对端进程及其对端进程调用stack,找到阻塞函数,如果system_app_anr@XXXX被截断,可以查看traces.txt文件;
4)如果是nativepollonce,可以查看BlockMonitor日志,是否主线程有比较耗时的操作;CPU占用率情况,iowait情况;最有效的是分析systrace日志;
5)如果system_app_anr@XXXX中没有发生anr的调用stack,一般是三种情况:
- ANR进程处于D state,导致无法响应SIG 3信号,从而导致无法打印stack,可以通过sysrq信息确认;
- ART处于死锁状态,由于ART本身bug导致无法处理SIG 3操作;
- ANR进程获取不了足够的时间无法打印调用stack。
3、Binder阻塞ANR案例分析
3.1 ANR主栈分析
可以明确,这个ANR发生的原因,是Binder阻塞:
此时主线程,阻塞在isCoverOpen函数。
3.2 Binder阻塞分析
查找对应的binder transaction信息,分析binder被阻塞的原因。
(1)确认ANR发生的binder
阻塞的binder是aod发生给systemserver的,但看不到systemserver的Binder线程,故需要看看systemserver的Binder情况。
(2)确认对端binder
分析2618的主栈。
在binder transcation表中可以看到,systemserver进程的16个Binder线程,全部被阻塞在给hwfacerecognize发送消息。
在Android中一个进程最多会使用16个binder线程,systemserver的全部Binder线程都被阻塞,故不能再分配Binder线程处理其他的Binder消息,导致其他进程给systemserver发送Binder消息时是会被阻塞,且没有对端binder线程的。
故问题的焦点,转移到了hwfacerecognize(PID 727)的进程上。
(3)业务代码分析
hwfacerecognize(PID 727)是人脸识别的进程,联合人脸识别模块的分析,发现是727进程出现crash。
稳定性优化需要开发者持续运营和维护,并对稳定性涉及的多项知识领域进行了解,才能更好的设计出稳定性优化方案,进而提升用户使用体验。后续我们将继续围绕稳定性问题做系列解读。