Running perfetto in detached mode
This document describes the --detach
and --attach
advanced operating modes
of the perfetto
cmdline client.
WARNING: The use of --detach
and --attach
is highly discouraged because of
the risk of leaking tracing sessions and accidentally leaving tracing on for
arbitrarily long periods of time.
TIP: If what you are looking for is just a way to grab a trace in background
(e.g., while the USB cable / adb is disconnected) from the adb shell simply
use --background
.
Use case
By default the tracing service traced
keeps the lifetime of a tracing session
attached to the lifetime of the perfetto
cmdline client that started it.
This means that a killall perfetto
or kill $PID_OF_PERFETTO
is sufficient
to guarantee that the tracing session is stopped.
There are rare occasions when this is undesirable; for example, this mode of operation was designed for the Traceur app (on-device tracing UI for Android).
When required by the user, Traceur needs to enable tracing in the background,
possibly for very long periods of time. Because Traceur is not a persistent service (and even if it was, it could be
still low-memory-killed), it cannot just use --background
; this is
because the Android framework kills any other process in the same process group
when tearing down an app/service, and this would including killing forked
perfetto
client obtained via --background
.
Operation
--detach=key
decouples the lifetime of the cmdline client from the lifetime
of the tracing session.
The key
argument is an arbitrary string passed by the client to later
re-identify the session using --attach=key
.
Once detached, the cmdline client will exit (without forking any bg process) and
the traced
service will keep the tracing session alive. Because of the exit,
a client that wants to use --detach
needs to set the
write_into_file
option in the trace config, which
transfers the responsibility of writing the output trace file to the
service (see the examples section).
A detached session will run until either:
- The session is later re-attached and stopped.
- The time limit specified by the
duration_ms
argument in the trace config is reached.
--attach=key
re-couples the lifetime of a new cmdline client invocation with
an existing tracing session identified by key
.
For security reasons the service allows a client to re-attach to a tracing
session only if the Unix UID of the re-attaching client matches the UID of the
client that originally started the session and detached.
Overall --attach=key
makes the perfetto
cmdline client behave as if it was
never detached. This means that:
- sending a
SIGKILL
(or Ctrl-C) to the client will gracefully stop the tracing session. - If the
duration_ms
time limit is hit, the client will be informed by the service and exit soon after.
When re-attaching it is possible to also specify a further --stop
argument.
--stop
will gracefully terminate the tracing session immediately after
re-attaching (This is to avoid a race where SIGKILL is sent too early, before
the client gets a chance to attach or even register the signal handler).
No other cmdline argument other than --stop
can be passed when using
--attach
.
--is_detached=key
can be used to check whether a detached session is running.
The cmdline client will return quickly after the invocation with the following
exit code:
- 0 if the session identified by
key
exists and can be re-attached. - 1 in case of a general error (e.g. wrong cmdline, cannot reach the service).
- 2 if no detached session with the given
key
is found.
Examples
Capturing a long trace in detached mode
echo '
write_into_file: true
# Long tracing mode, periodically flush the trace buffer into the trace file.
file_write_period_ms: 5000
buffers {
# This buffer needs to be big enough just to hold data between two consecutive
# |file_write_period|s (5s in this examples).
size_kb: 16384
}
data_sources {
config {
name: "linux.ftrace"
ftrace_config {
ftrace_events: "sched_switch"
}
}
}
' | perfetto -c - --txt --detach=session1 -o /data/misc/perfetto-traces/trace
sleep 60
perfetto --attach=session1 --stop
# At this point the trace file is fully flushed into
# /data/misc/perfetto-traces/trace.
Start in detached ring-buffer mode. Later stop and save the ring buffer
echo '
write_into_file: true
# Specify an arbitrarily long flush period. Practically this means: never flush
# unless trace is stopped.
# TODO(primiano): an explicit no_periodic_flushes argument would be nicer. Maybe
# we could repurpose the 0 value?
file_write_period_ms: 1000000000
buffers {
# This will be the size of the final trace.
size_kb: 16384
}
data_sources {
config {
name: "linux.ftrace"
ftrace_config {
ftrace_events: "sched_switch"
}
}
}
' | perfetto -c - --txt --detach=session2 -o /data/misc/perfetto-traces/trace
# Wait for user input, or some critical event to happen.
perfetto --attach=session2 --stop
# At this point the trace file is saved into
# /data/misc/perfetto-traces/trace.
Start tracing with a time limit. Later re-attach and wait for the end
echo '
duration_ms: 10000
write_into_file: true
buffers {
size_kb: 16384
}
data_sources {
config {
name: "linux.ftrace"
ftrace_config {
ftrace_events: "sched_switch"
}
}
}
' | perfetto -c - --txt --detach=session3 -o /data/misc/perfetto-traces/trace
sleep 3
perfetto --attach=session3
# The cmdline client will stay up for 7 more seconds and then terminate.