Android 上的高级系统 Tracing

本指南深入探讨在 Android 上采集系统 trace,建立在 System Tracing 指南中介绍的概念基础上。

在继续之前,你应该熟悉使用 Perfetto UIrecord_android_trace 脚本采集系统 trace 的基础知识。

本指南涵盖这些工具抽象掉的底层详细信息,包括:

前提条件:启用 tracing 服务

Perfetto 的tracing 守护进程(traced)内置在 Android 中,但它们仅在 Android 11 (R) 及更新版本上默认启用。

如果你使用的是 Android 9 (P) 或 **Android 10 (Q)**,你必须首先运行以下命令来启用 tracing 服务:

# 仅在非 Pixel 手机上的 Android 9 (P) 和 10 (Q) 上需要。 adb shell setprop persist.traced.enable 1

NOTE: 如果你使用的是早于 9 (P) 的 Android 版本,设备上的工具将无法工作。 你必须使用 record_android_trace 脚本。

使用设备上的 /system/bin/perfetto 命令进行记录

record_android_trace 脚本是设备上 /system/bin/perfetto 二进制文件的包装器。对于大多数用例,推荐使用该脚本,但你也可以直接调用二进制文件以获得更多控制权。

# 直接调用设备上二进制文件的示例。 adb shell perfetto \ # 设备上输出文件的路径。 # 采集 trace 的时间。 -o /data/misc/perfetto-traces/trace_file.perfetto-trace \ # 采集 trace 的时间。 -t 20s \ # 要采集的 atrace 类别。 sched freq idle am wm gfx view binder_driver hal dalvik input res memory

然而,直接使用 adb shell perfetto 时有几个注意事项需要注意:

使用完整的 Trace Config

要完全控制 tracing 过程,你可以提供完整的 trace config 文件,而不是使用命令行标志。这允许你启用多个数据源并微调它们的设置。

有关编写 trace config 的详细指南,请参阅 Trace Configuration 页面。

WARNING: 下面的命令在 Android P 上不起作用,因为 --txt 选项是在 Q 中引入的。 应该使用二进制 protobuf 格式;详细信息可以在 [Trace configuration 页面](https://perfetto.dev/docs/concepts/config#pbtx-vs-binary-format)中找到。

如果你在 Mac 或 Linux 主机上运行,或者在 Windows 上使用基于 bash 的终端,你可以使用以下内容:

cat<<EOF>config.pbtx duration_ms: 10000 buffers: { size_kb: 8960 fill_policy: DISCARD } buffers: { size_kb: 1280 fill_policy: DISCARD } data_sources: { config { name: "linux.ftrace" ftrace_config { ftrace_events: "sched/sched_switch" ftrace_events: "power/suspend_resume" ftrace_events: "sched/sched_process_exit" ftrace_events: "sched/sched_process_free" ftrace_events: "task/task_newtask" ftrace_events: "task/task_rename" ftrace_events: "ftrace/print" atrace_categories: "gfx" atrace_categories: "view" atrace_categories: "webview" atrace_categories: "camera" atrace_categories: "dalvik" atrace_categories: "power" } } } data_sources: { config { name: "linux.process_stats" target_buffer: 1 process_stats_config { scan_all_processes_on_start: true } } } EOF ./record_android_trace -c config.pbtx -o trace_file.perfetto-trace

或者,当直接使用设备上的命令时:

cat config.pbtx | adb shell perfetto -c - --txt -o /data/misc/perfetto-traces/trace.perfetto-trace

或者,首先推送 trace config 文件,然后调用 perfetto:

adb push config.pbtx /data/local/tmp/config.pbtx adb shell 'cat /data/local/tmp/config.pbtx | perfetto --txt -c - -o /data/misc/perfetto-traces/trace.perfetto-trace'

NOTE: 由于严格的 SELinux 规则,在 Android 的非 root 版本上,直接将文件路径作为 -c /data/local/tmp/config 传递将失败,因此需要上面的 -c - + stdin 管道。 从 Android 12 (S) 开始,可以使用 /data/misc/perfetto-configs/ 代替。

使用 adb pull /data/misc/perfetto-traces/trace ~/trace.perfetto-trace 拉取文件并在 Perfetto UI 中打开它。

NOTE: 在 Android 10 之前的设备上,adb 无法直接拉取 /data/misc/perfetto-traces。 使用 adb shell cat /data/misc/perfetto-traces/trace > trace.perfetto-trace 作为解决方法。

perfetto 命令行界面的完整参考可以在[这里](/docs/reference/perfetto-cli.md)找到。

独占 Tracing 会话

Perfetto 旨在支持来自不同源(例如,adb、设备上的应用程序、自动化测试)的多个并发tracing 会话。虽然这适用于大多数数据源,但某些高级功能无法可靠地多路复用,并且敏感的性能测量需要最小化来自其他 trace 的干扰。在这些情况下,Perfetto 需要保证没有其他tracing 会话处于活动状态。

为了解决这个问题,Perfetto 提供了"独占"模式。当在独占模式下启动会话时,它确保没有其他会话正在运行,提供干净的tracing 环境。这由 TraceConfig 中的 exclusive_prio 字段控制。

何时使用独占模式

你应该在以下情况下使用独占会话:

行为

独占会话具有以下行为:

如何启用

要启动独占会话,请在你的 trace config 文件中添加 exclusive_prio 字段。

此功能从 Perfetto v52 和 Android 的 25Q3+ 开始可用。

duration_ms: 10000 buffers: { size_kb: 8192 } # 请求优先级为 10 的独占会话。 # 这将中止任何正在运行的会话(前提是它们的优先级较低)并阻止 # 优先级较低或相等的新会话。 exclusive_prio: 10 data_sources: { config { name: "linux.ftrace" ftrace_config { # 像 funcgraph 这样的高级功能现在可以更可靠地使用。 function_graph: true ftrace_events: "sched/sched_switch" } } }