在 ANR分析(一) 中,我们已经了解了anr产生的原因,我们现在要排查,找出问题,总体步骤是:
1、导出ANR日志信息,根据日志信息,判断确认发生ANR的包名类名,进程号,发生时间,导致ANR原因类型等。
2、关注系统资源信息,包括ANR发生前后的CPU,内存,IO等系统资源的使用情况。
3、查看主线程状态,关注主线程是否存在耗时、死锁、等锁等问题,判断该ANR是App导致还是系统导致的。
4、结合应用日志,代码或源码等,分析ANR问题发生前,应用是否有异常,其中具体问题具体分析。
一、ANR调试
对于service、broadcast、provider、input发生ANR后,中控系统会马上去抓取现场的信息,用于调试分析。收集的信息包括如下:
1. 将am_anr信息输出到EventLog,也就是说ANR触发的时间点最接近的就是EventLog中输出的am_anr信息
2. 收集以下重要进程的各个线程调用栈trace信息,保存在 data/anr/traces.txt文件
当前发生ANR的进程,system_server进程以及所有persistent进程 audioserver, cameraserver, mediaserver, surfaceflinger等重要的native进程,分析CPU使用率排名前5的进程。
3. 将发生ANR的reason以及CPU使用情况信息输出到main log
4. 将traces文件和CPU使用情况信息保存到dropbox,即data/system/dropbox目录
5. 对用户可感知的进程则弹出ANR对话框告知用户,对用户不可感知的进程发生ANR则直接杀掉
二、log 文件
例如,如下anr的 log 信息: 16% 3105/system_server: 7.9% user + 8.1% kernel / faults: 6549 minor 0.3% 2779/media.codec: 0.2% user + 0% kernel / faults: 35716 minor 10% 763/surfaceflinger: 8.2% user + 2.6% kernel / faults: 419 minor ...
0.1% 27263/kworker/4:2: 0% user + 0.1% kernel
0.1% 27743/kworker/0:0: 0% user + 0.1% kernel
15% TOTAL: 10% user + 5.4% kernel + 0.1% iowait + 0.2% irq + 0% softirq
ANR前后cpu的使用情况:
a. 如果CPU使用量接近100%,说明当前设备很忙,有可能是CPU饥饿导致ANR b. 如果CPU使用量很少,说明主线程被block了 c. 如果IOwait很高,说明主线程在进行I/O操作
三、trace文件:
log 文件只是告诉你 ANR 发生时间,但是并具体详细的信息,这时候就得查看 trace 文件(App 的进程发生 ANR 时,系统让活跃的 Top 进程都进行了一下 dump,进程中的各种Thread 就都 dump 到这个 trace 文件里了,所以 trace 文件中包含了每一条线程的运行时状态)。
拉取trace文件:
adb pull data/anr/anr_2023-2-23-17-30-41-366
主要分析: 1、进程号、ANR发生时间和进程名称 DALVIK THREADS (14): "main" prio=5 tid=1 Sleeping 2、线程名、线程优先级、线程号、线程当前状态
参考: