Advanced System Tracing on Android
This guide dives deeper into recording system traces on Android, building on the concepts introduced in the System Tracing guide.
Before you continue, you should be familiar with the basics of recording a
system trace using either the
Perfetto UI or
the
record_android_trace
script.
This guide covers the lower-level details that these tools abstract away, including:
- Enabling the Perfetto tracing services on older Android versions.
- Using the on-device
/system/bin/perfetto
binary directly. - Writing and using a full trace config for advanced customization.
Prerequisites: Enabling Tracing Services
Perfetto's tracing daemons (traced
) are built into Android, but they are only
enabled by default on Android 11 (R) and newer.
If you are using Android 9 (P) or Android 10 (Q), you must first enable the tracing services by running the following command:
# Needed only on Android 9 (P) and 10 (Q) on non-Pixel phones.
adb shell setprop persist.traced.enable 1
NOTE: If you are using a version of Android older than 9 (P), the on-device
tools will not work. You must use the
record_android_trace
script.
Recording using the on-device /system/bin/perfetto command
The record_android_trace
script is a wrapper around the on-device
/system/bin/perfetto
binary. For most use cases, the script is recommended,
but you can also invoke the binary directly for more control.
# Example of invoking the on-device binary directly.
adb shell perfetto \
# The path to the output file on device.
# Time to record the trace.
-o /data/misc/perfetto-traces/trace_file.perfetto-trace \
# Time to record the trace.
-t 20s \
# The atrace categories to record.
sched freq idle am wm gfx view binder_driver hal dalvik input res memory
However, there are several caveats to be aware of when using
adb shell perfetto
directly:
Stopping the trace:
Ctrl+C
does not work reliably withadb shell perfetto
. It is only propagated correctly when using an interactive PTY-based session (i.e., runningadb shell
first, thenperfetto
inside the shell). For long-running traces, it is safer to use the--background
flag andkill
the process by its PID. See the Tracing in the Background guide for more.Passing trace configs: On non-rooted devices before Android 12, SELinux rules prevent the
perfetto
process from reading config files from world-writable locations like/data/local/tmp
. The recommended workaround is to pipe the config via standard input:cat config.pbtx | adb shell perfetto -c -
. Since Android 12, you can place configs in/data/misc/perfetto-configs
and pass the path directly.Pulling trace files: On devices before Android 10,
adb pull
may not be able to access the trace file directly due to permissions. The workaround is to useadb shell cat
:adb shell cat /data/misc/perfetto-traces/trace > trace.pftrace
.
Using a Full Trace Config
For full control over the tracing process, you can provide a complete trace config file instead of using command-line flags. This allows you to enable multiple data sources and fine-tune their settings.
See the Trace Configuration page for a detailed guide on writing trace configs.
WARNING: The below command does not work on Android P because the --txt
option
was introduced in Q. The binary protobuf format should be used instead; the
details of this can be found on the
Trace configuration page.
If you are running on a Mac or Linux host, or are using a bash-based terminal on Windows, you can use the following:
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
Or alternatively, when using directly the on-device command:
cat config.pbtx | adb shell perfetto -c - --txt -o /data/misc/perfetto-traces/trace.perfetto-trace
Alternatively, first push the trace config file and then invoke 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: because of strict SELinux rules, on non-rooted builds of Android, passing
directly the file path as -c /data/local/tmp/config
will fail, hence the
-c -
+ stdin piping above. From Android 12 (S), /data/misc/perfetto-configs/
can be used instead.
Pull the file using
adb pull /data/misc/perfetto-traces/trace ~/trace.perfetto-trace
and open it
in the Perfetto UI.
NOTE: On devices before Android 10, adb cannot directly pull
/data/misc/perfetto-traces
. Use
adb shell cat /data/misc/perfetto-traces/trace > trace.perfetto-trace
to work
around.
The full reference for the perfetto
cmdline interface can be found
here.