Android ANR 分析(trace 文件的产生流程上)
收集需要 dump trace 的进程并给对应进程发送 dump trace 的信号
1.当一些带有超时机制的系统消息(如:Service 的创建)判定超时后,会调用系统服务 AMS 接口,收集 ANR 相关信息并存档(data/anr/trace, data/system/dropbox)
2.进入到 AMS 中,AppError 会先进行筛选(1.当前进程正在进行 dump 流程 2.已经发生 crash 3. 已经被系统 kill 4.系统是否正在关机等情况),如果都不符合,则认为当前进程发生了 anr。
3.接下来系统在判断当前 ANR 进程对用户是否可感知,然后开始统计与该进程由关联的进程,或者一些系统核心服务进程的信息(例如与应用交互的 SurfaceFligner,System Server 等系统进程),如果这些系统服务进程在响应时被阻塞,那么将导致应用进程 IPC 通信过程被卡死。接着获取其他系统核心进程,因为这些服务进程是 init 进程直接创建的,并不在 SystemServer 或 Zygote 进程管理范围。
firstPids 队列:第一个是 ANR 进程,第二个是 system_server,剩余是所有 persistent 进程;Native 队列:是指/system/bin/目录的 mediaserver,sdcard 以及 surfaceflinger 进程;lastPids 队列: 是指 mLruProcesses 中的不属于 firstPids 的所有进程。
4.在收集完第一步信息后,接下来便开始统计各进程本地的更多信息,如虚拟机信息,java 线程状态及堆栈。首先会弹出一个 ANR 的对话框,然后向 UI 线程发送 SHOW_NOT_RESPONDING_MSG 消息
5.当 UI 线程收到该消息后,会调用 dumpStackTraces 函数:
最重要的一点:向目标进程发送 SINAL_QUIT(进程中的 Signal Catcher 会进行阻塞检测收集信息后面讲),firstPids 列表中的进程, 两个进程之间会休眠 200ms, 可见 persistent 进程越多,则时间越长. top 5 进程的 traces 过程中, 同样是间隔 200ms, 另外进程使用情况的收集也是比较耗时.
总结
将 am_anr 信息输出到 EventLog(分析 anr 问题时先看该 log)获取重要进程的信息,java 进程的,和 native 的进程将 ANR 的 Reason 和 CPU 使用的情况输出到 main_log 在将 CPU 使用情况和进程的 trace 文件信息,在保存到 drpobox 文件下向收集到的进程发送 SINAL_QUIT 信号。
版权声明: 本文为 InfoQ 作者【北洋】的原创文章。
原文链接:【http://xie.infoq.cn/article/27269585eba6f936e4c479276】。文章转载请联系作者。
评论