ANR

419 阅读2分钟

ANR

​ ANR日志分析步骤

确认时间点(非必需)

​ mobilelog文件夹下的events_log,搜索关键字"am_anr",这一步用于确认ANR时间点,可以搜索到类似如下信息

04-29 10:00:57.240 1267 1341 I am_anr : [0,6073,com.android.dialer,952745541,Input dispatching timed out

比如上面这行表示ANR类型为Input dispatching timed out, 这种anr的原因的是在viewrootimpl分发事件时,并没有找到focuswindow导致的

这一步确认时间点在:10:00:57,进程号:6073

查看ANR时的CPU以及IO率

这一步一般来说能基本定位是什么造成了ANR,是IO高还是CPU高,如两者都不是,需进入第三步trace日志分析环节 查看mobilelog文件夹下的main_log,搜索关键字"ANR in",可以看到当时的CPU以及IO率,这一个环节一般来讲主要是看发生ANR时的CPU使用情况,CPU是否吃紧,还有需要注意iowait的占有率,如果占比比较高,则排查的方向要倾向与读取文件操作有关的信息,可以看trace日志中有没有一些读取文件或者操作SD卡的动作

分析ANR时的堆栈(必需,最重要的环节)

ANR发生后会在data/anr下生成trace.txt,这份trace务必要与moile日志匹配,一般来讲直接先看tid=1的堆栈即对应主线程,因为ANR都是主线程执行超时导致关于trace日志的分析是ANR问题分析最重要的一个环节,下面将列出平时项目中遇到的ANR案例类型

ANR常见类型归纳1.主线程Binder调用等待超时比如下面的这段

image.png

很明显当时在做Binder通信,并没有waiting to lock等代表死锁的字样,那么说明这个案例即有可能是在等Binder对端响应,我们知道Binder通信对于发起方来说是默认是阻塞等待响应,只有有了返回结果后才会继续执行下去,当然了可以给接口设置oneway声明,这样的话binder请求就是异步请求,这里不多说

所以,如上这个案例中需要找到对端是哪个进程,这个进程当时在做什么,这时候就需要找到anr文件夹下另外一个文件binderinfo,这里需要找到与我们发起方进程1461通信的是哪个进程

image.png

可以看到是1666号这个进程,再回到trace中看下,这个进程当时在做什么

image.png

可以看到当时对端在做消息的读取,也就是说这里出了问题,很明显这里我们无法修改,我们这个问题在于主线程执行了Binder请求,对端迟迟未返回便很容易出现这个问题,当前做法异步中执行