如何分析Perfetto Trace中App因Uninterruptible Sleep触发的ANR
定位阻塞的系统调用
在Perfetto的Processes面板找到触发ANR的目标进程,切换到Syscalls标签,筛选出ANR时间段内的系统调用记录,重点关注进程进入Uninterruptible Sleep(D状态)时发起的调用——比如read/write(文件或设备IO)、fsync、wait这类易阻塞的操作。结合Trace Events里的syscall_entry和syscall_exit事件,确认调用的参数(如操作的文件路径、设备节点),明确是磁盘IO、外设IO还是其他内核操作引发的阻塞。关联内核IO操作细节
切换到Kernel面板,查看ANR时段内的磁盘IO事件(如block_rq_issue、block_rq_complete),找到与目标进程PID绑定的IO请求,检查是否存在长时间未完成的读写任务,或是磁盘队列持续处于高负载状态。同时排查同一时段内是否有其他进程在执行大量磁盘读写(如系统更新、大文件拷贝),抢占了IO资源导致目标进程阻塞。追溯App代码触发逻辑
回到App面板,查看目标进程的Java/Kotlin堆栈(Android App场景),定位进入D状态前最后执行的应用代码,确认是否在主线程发起了同步IO操作(比如直接读写大文件、访问慢速外部存储)。如果App包含Native层代码,同步查看Native堆栈,确认是否存在未设置超时的阻塞系统调用,导致进程陷入无法中断的睡眠状态。检查系统资源状态
在System Stats面板查看ANR时段的内存状态,确认是否因内存不足触发了页交换(swap)——频繁的swap会导致磁盘IO激增,进程因等待页加载陷入D状态。同时检查CPU负载,排除CPU被其他进程占满导致内核无法及时处理IO请求的可能(注:D状态通常与CPU无关,主要对应IO等待,但极端CPU负载可能间接影响IO调度)。补充场景验证
若为Android系统,查看Battery面板是否有系统省电策略触发的磁盘降速,导致IO操作延迟。此外,尝试在不同设备或系统版本上复现问题,确认是App代码逻辑问题,还是特定系统环境的兼容性问题。
内容的提问来源于stack exchange,提问作者lucky1928

