疑难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、查看日志
日志下载:
https://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实战干货,请关注下面“千里马学框架”

<think>我们正在讨论ANR文件的分析。ANR代表"Application Not Responding",即应用程序无响应。这种文件通常在Android设备上生成,当应用程序在主线程上阻塞太久时触发。 用户提供的文件名格式为:anr_2025-10-21-10-29-04-308,这是典型的ANR日志文件命名方式(包含时间戳)。 分析ANR文件的主要目标是找出导致主线程阻塞的原因。常见的工具和方法如下: 1. **使用adb命令获取ANR文件**: 通常,我们可以通过adb从设备中提取ANR文件: ``` adb pull /data/anr/anr_2025-10-21-10-29-04-308 ``` 注意:需要设备有root权限,否则可能无法访问/data/anr目录。如果没有root权限,可以尝试使用`adb bugreport`命令生成完整的bug报告,其中会包含ANR文件。 2. **直接查看ANR文件内容**: ANR文件是文本文件,可以用任何文本编辑器打开。关键部分包括: - 导致ANR的进程ID和包名 - 主线程的堆栈跟踪(stack trace),这通常会指出阻塞的位置 - 可能还包括其他线程的状态 3. **使用Android Studio分析**: Android Studio内置了分析工具,可以查看堆栈跟踪。如果ANR文件是来自开发中的应用程序,可以直接在Android Studio的Logcat中查看,或者将文件导入。 4. **使用Traceview或Perfetto**: 有时ANR文件中会包含跟踪信息(trace),我们可以使用Traceview(旧版)或Perfetto(新版)来查看这些跟踪文件,从而分析主线程上的卡顿。 5. **使用第三方工具**: 有一些第三方工具可以辅助分析ANR,比如: - [Android ANR Analyzer](https://github.com/ACRA/acra) (ACRA项目的一部分,但主要用于错误报告,也可以分析ANR) - 在线ANR分析工具(需谨慎,因为上传日志可能涉及隐私) 6. **分析堆栈跟踪的关键点**: 在堆栈跟踪中,我们需要关注主线程(通常名为“main”)的状态。常见的导致ANR的原因有: - 在主线程中进行网络操作 - 主线程中进行文件读写(尤其是大文件) - 主线程中进行复杂的计算 - 死锁 7. **检查CPU使用情况**: ANR文件中通常会包含发生ANR时CPU的使用情况,我们可以查看是否有其他进程或线程占用了大量CPU,导致我们的应用得不到足够的资源。 8. **检查内存信息**: 有时ANR是由内存不足引起的,因此查看内存信息也很重要。 9. **使用`strict mode`预防**: 在开发阶段,我们可以启用严格模式(StrictMode)来帮助检测主线程上的磁盘操作或网络访问。 注意:由于ANR文件名中包含时间戳,我们可以知道问题发生的具体时间,这有助于结合其他日志进行定位。 由于用户的问题是关于特定文件(anr_2025-10-21-10-29-04-308)的分析,因此我们主要关注如何分析这个文件的内容。 步骤建议: 1. 获取文件:通过adb或从设备上直接导出(如果有权限)。 2. 打开文件,查看主线程堆栈,定位到代码中导致阻塞的位置。 3. 分析堆栈,查看是否有明显的长时间操作在主线程中。 4. 检查文件中的CPU负载和内存信息,看是否有系统资源瓶颈。 5. 如果堆栈信息不足以定位,可能需要重现问题并使用调试工具(如Perfetto)进行更详细的跟踪。 注意:如果用户是开发者,那么他们应该能够在自己的代码中找到对应的堆栈位置。如果是系统应用或没有源码,可能需要反编译或者查看系统日志。 由于ANR文件可能包含敏感信息,请确保在安全的环境下处理。 生成相关问题: 1. 如何在没有root权限的情况下获取ANR文件? 2. ANR文件中常见的堆栈信息有哪些模式? 3. 如何预防ANR的发生? 4. 使用Perfetto分析ANR的步骤是什么? </think>### 分析 ANR 文件的方法与工具 ANR(Application Not Responding)文件是 Android 系统在应用主线程阻塞超过 5 秒时生成的诊断日志,文件名格式通常为 `anr_年------序列号`(如 `anr_2025-10-21-10-29-04-308`)。以下为分析方法和工具: --- #### **一、核心分析方法** 1. **定位主线程阻塞点** 检查文件中 `"main" pid=XXX` 部分的堆栈跟踪(stack trace),识别阻塞主线程的代码位置,例如: ```plaintext "main" prio=5 tid=1 Native | group="main" sCount=1 dsCount=0 flags=1 obj=0x74e8f7e0 | sysTid=12345 nice=-10 cgrp=default sched=0/0 handle=0x7f8f4e4500 | state=S schedstat=( 123456789 987654321 1234 ) utm=10 stm=15 core=0 HZ=100 | stack=0x7fe9bc4000-0x7fe9bc6000 at com.example.app.MainActivity.longOperation(MainActivity.java:25) <-- 阻塞点 ``` 2. **检查 CPU 负载** 在文件末尾的 `CPU usage` 部分,确认 ANR 发生时: - 应用进程的 CPU 是否达到 100% - 是否有其他进程(如系统服务)过度占用 CPU 3. **分析锁竞争** 搜索文件中 `held by` 关键字,检查线程间死锁或资源争用: ```plaintext "Thread-2" waiting for lock <0x0f1e3d88> held by "main" ``` --- #### **二、专业工具推荐** 1. **Android Studio 内置工具** - **Logcat**:直接解析 ANR 文件堆栈信息 - **Profiler**:结合 CPU 性能分析定位耗时操作 - **Layout Inspector**:检查 UI 线程阻塞(适用于界面卡顿型 ANR) 2. **命令行工具** - `adb pull /data/anr/anr_2025-10-21-10-29-04-308`:导出文件 - `adb bugreport`:获取完整系统诊断包(包含所有 ANR 文件) 3. **第三方工具** - **[Perfetto](https://perfetto.dev/)**:可视化分析系统级性能数据 - **[ANR-WatchDog](https://github.com/SalomonBrys/ANR-WatchDog)**(开发阶段预防):主动检测 ANR 4. **在线解析工具** - **[GitHub: ANR analyzer](https://github.com/google/anr-analyzer)**:自动提取关键信息 ```bash java -jar anr-analyzer.jar anr_2025-10-21-10-29-04-308 ``` --- #### **三、操作流程** 1. **导出文件** ```bash adb shell ls /data/anr # 列出 ANR 文件 adb pull /data/anr/anr_2025-10-21-10-29-04-308 # 导出到本地 ``` > 注:需开启 USB 调试且设备已 ROOT,否则通过 `adb bugreport` 导出完整报告后解压提取。 2. **关键检查项** - 主线程堆栈中是否有 `Binder` 调用、文件 I/O 或网络请求 - CPU 使用率是否异常(如系统进程占比 >60%) - 内存不足警告(如 `lowmemorykiller` 日志) 3. **代码修复建议** - 耗时操作移至工作线程(如 `AsyncTask` 或 `Coroutine`) - 避免主线程同步 IPC 调用 - 使用 `StrictMode` 检测磁盘/网络操作[^1] --- #### **四、高级场景** - **系统ANR**:若进程名为 `system_server`,需检查系统服务(如 AMS、WMS) - **Native 层阻塞**:文件中出现 `nativePollOnce` 时,需使用 `systrace` 分析 - **后台 ANR**:关注 `BroadcastQueue` 或 `Service` 执行超时
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

千里马学框架

帮助你了,就请我喝杯咖啡

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值