Android Perfetto 系列 12:Trace 数据流与丢失排查
一份 Trace 能在 UI 里打开、SQL 也查得到行,仍可能在采集中丢过数字。线程状态缺一段、进程名对不上、Track Event 只有 ID 没有名称时,先查数据丢在哪一层,再决定哪些分析还能继续。
SQL 只能度量留下来的事件。丢失发生在 ftrace、producer 共享内存还是 central buffer,作用的查询不同。看到一条 ftrace loss,我不会立刻扔掉整份 Trace;先查它冲击的是调度、业务标记,还是帧数字。
下文沿事件从内核进入 Trace 文件的路径检查 ftrace、producer 共享内存、central buffer、增量状态和 flush。每一处都有对应的 stats 线索和下一次采集时可调整的配置。
Perfetto 系列文章
- Android Perfetto 系列目录
- Android Perfetto 系列 1:Perfetto 工具简介
- Android Perfetto 系列 2:Perfetto Trace 抓取
- Android Perfetto 系列 3:熟悉 Perfetto View
- Android Perfetto 系列 4:使用命令行在本地打开超大 Trace
- Android Perfetto 系列 5:Android App 基于 Choreographer 的渲染流程
- Android Perfetto 系列 6:为什么是 120Hz?高刷新率的长处与挑战
- Android Perfetto 系列 7:MainThread 和 RenderThread 解读
- Android Perfetto 系列 8:深入理解 Vsync 机制与表现分析
- Android Perfetto 系列 9:CPU 信息解读
- Android Perfetto 系列 10:Binder 调度与锁较量
- Android Perfetto 系列 11:PerfettoSQL、Trace Processor 与回归检测
- Android Perfetto 系列 12:Trace 数据流与丢失排查
- Android Perfetto 系列 13:Perfetto SDK、Track Event 与 App 现场 Trace
- Android Perfetto 系列 14:heapprofd 与内存 Profiling
- Android Perfetto 系列 15:Boot Trace、长时间现场 Trace 与偶发问题抓取
- Android Perfetto 系列 16:GPU、Power Counters 与硬件瓶颈分析
- Android Perfetto 系列 17:专项场景自动化、问题清单与平台体系
- Android Perfetto 系列 18:响应速度实战,从输入事件到首帧反馈
- 短片(B站) - Android Perfetto 基础和案例分享
- 视频(B站) - Android Perfetto 分享 - 出图类型分享:AOSP、WebView、Flutter + OEM 平台优化分享
Trace 有数据,不代表证据完整
Perfetto 不是无损录像机。它的写入路径为了低开销做了异步化:producer 先写自己的共享内存;共享内存页满、Trace 结束或 flush 时,再提交给 traced 的 central buffer;之后在 Trace 结束、streaming 或周期写文件时落到输出文件。
任意一段跟不上,都会产生 data loss。flush 做的只是让 producer 把未提交的数据交给 tracing service,并不等同于直接写进文件。
分析前先做一次完整性检查:
1 | 打开 Trace |

示意图:ftrace 内核缓冲、producer 共享内存与中央缓冲是不同环节;flush 不等于文件落盘。
检查结果应和方向窗口一起保存;整份 Trace 有统计结果,不等于目标窗口里的每种统计结果源都完整。
一个常见现场是这样的:Perfetto UI 里能找到卡顿帧,也能看到主线程切片,但 stats 里同时出现 ftrace_cpu_has_data_loss。这时要先分清证据来源。
Android 12+ 且启用 android.surfaceflinger.frametimeline 时,如果方向窗口内 expected/actual FrameTimeline slices 存在,并且没有 parser/pairing 异常,FrameTimeline 仍可作为入口。App SDK Track Event 也可能仍能帮助定位业务阶段。
但来自 atrace/ftrace 的 Choreographer、HWUI、RenderThread、SurfaceFlinger 切片,以及 Runnable/wakeup 结论,都要随 ftrace loss 降级。“没有看到 Runnable 等待”不能写成“没有调度难题”。
数据从哪里走到 Trace 文件
Perfetto 的数据路径可以拆成四段:
| 阶段 | 发生在哪里 | 常见问题 |
|---|---|---|
| 数据源产生事件 | traced_probes、App 进程、native 进程、heapprofd | 事件开太多,突发写入太密 |
| producer 共享内存 | 每个 producer 与 traced 之间的共享内存 | producer 写得太快,traced 没来得及搬 |
| central buffer(tracing service 的中央缓冲区) | TraceConfig 里的 buffers | Ring 覆盖旧数据,Discard 丢新数字 |
| 输出文件与解析 | trace 文件、Trace Processor | 长 Trace 写文件不及时,导入排序或 clock 同步异常 |
增量状态是跨阶段议题,不是独立传输路径。Track Event 的 track descriptor、interned strings,以及进程/线程元数据这类上下文 packet 一旦被覆盖或缺包,后续事件可能只剩 ID,或者被 Trace Processor 跳过。
linux.ftrace 还多一段内核 per-CPU buffer。内核事件先进入每个 CPU 的 ftrace per-CPU buffer,再由 traced_probes 周期读取。打开 sched_switch、sched_waking、Binder、IRQ 这类 ftrace tracepoint,以及部分 Camera/GPU vendor ftrace 事件后,这一段最容易出问题。
Binder 证据需要显式启用 binder_driver 或对应 binder ftrace events,并核对 ftrace_setup_errors;可用 category 和事件会随 Android/内核版本变化。
本文由News整理发布,仅供参考。

