疑难ANR原因分析-冻结导致直播讲解相关完整笔记

0 阅读4分钟

转载于:疑难ANR原因分析-冻结导致直播讲解相关完整笔记

背景:

ANR问题的复现可以看之前的文章有详细的复现: 疑难ANR问题复现及测试分析作业

分析过程:

anr一般问题可能是如下套路: 1、log看具体哪个进程哪个时间点anr,看看anr的类型 2、找到对应的anr的trace,看看anr对应主线程的是否有阻塞耗时等堆栈 上面方式确实对于应用自己原因耗时等引发anr确实够了,但是系统开发往往很多anr都没办法简单通过上述步骤找到原因,很可能trace中根本啥线索没有。

下面看看如果靠日志如何分析这类疑难anr的

1、抓取整个复现过程的所有日志

adb shell input keyevent 120;adb logcat -c;adb logcat -b all > ~/1.txt

2、查看日志 日志下载: share.weiyun.com/Dv0r2f3L 密码:l34bah

2.1 找ANR发生时间点,看看啥原因ANR

02-18 20:08:25.283   485   577 I WindowManager: ANR in input window owned by pid=3930. Reason: Input dispatching timed out ([Gesture Monitor] Screenshot 0 (server) is not responding. Waited 5000ms for MotionEvent(deviceId=4, eventTime=39032316052000, source=TOUCHSCREEN | STYLUS | BLUETOOTH_STYLUS, displayId=0, action=MOVE, actionButton=0x00000000, flags=0x00000000, metaState=0x00000000, buttonState=0x00000000, classification=NONE, edgeFlags=0x00000000, xPrecision=22.8, yPrecision=11.1, xCursorPosition=nan, yCursorPosition=nan, pointers=[0: (803.0, 1434.9)]), policyFlags=0x62000000)

日志可以看出ANR是在pid=3930,原因是因为MotionEvent在5秒前就已经发送,但是Gesture Monitor] Screenshot这个接受者根本没有响应导致,这里也打印表面原因就是Gesture Monitor] Screenshot没有响应导致的ANR,注意这里的 MotionEvent(deviceId=4, eventTime=39032316052000 这个事件的eventTime后续可以去InputDispatcher中进行追踪,看看啥时候派发的

2.2 针对这中无法得出anr结论的,anr查找到一般建议从源头出发开始查,比如inputDispatch相关的派发事件日志,这里正常情况下InputDispatcher没详细日志,因为比较频烦,所以这里需要自己手动开放一些InputDispatcher的相关日志: frameworks/native/services/inputflinger/dispatcher/DebugConfig.h 在这里插入图片描述这里标志位的开放大家可以和我一样写死为true,当然没有条件就用上面adb shell命令也可以

2.3 查看ANR时候派发的事件

MotionEvent(deviceId=4, eventTime=39032316052000 看看在InputDispatcher中是啥情况 在这里插入图片描述 明显可以看到InputDispatcher确实有在ANR时间的5秒前有进行相关的该事件派发,这里看看派发中是否有带上我们的 Gesture Monitor] Screenshot。

在这里插入图片描述 所以事件其实InputDispatcher确实有传递给Gesture Monitor] Screenshot,那么接下来就需要看看Gesture Monitor] Screenshot这个接受事件的情况。

2.3 接受事件相关打印 在这里插入图片描述 搜索日志看看相关打印: 在这里插入图片描述 可以看出Gesture Monitor] Screenshot最后一次接受触摸事件在02-18 20:08:20.276 ,在这个时间点之后就再也没有相关的事件打印了。

那么这里大家也就很容易想到看看Gesture Monitor] Screenshot这个进程3930到底发生了什么,在这个02-18 20:08:20.276 时间点后,日志搜索后发现重大的线索: 在这里插入图片描述 原来在20:08:20.289 时间点时候,Screenshot进程已经被冻结了,一旦进程被冻结了,那当然就不可以接受任何的事件,因为cpu压根就不会执行这个进程。问题到这里其实就向导于找到一个很充分的线索和理由了,但是还缺少一点验证,看看是否不冻结进程情况下,是否还会anr呢?

2.4 冻结关闭验证 安卓高版本开发者选项中其实是有相关的开关来关闭冻结相关的策略

在这里插入图片描述 把这个开关关闭后,验证发现死活无法复现了,但是一旦开启就很容易复现出相关anr,也可以看到每次anr前就会有screenshot相关的冻结打印freeze

am_freeze: [3930,com.android.systemui:screenshot]

更多framework实战干货,请关注下面公众号“千里马学框架”