1# Running perfetto in detached mode
2
3This document describes the `--detach` and `--attach` advanced operating modes
4of the `perfetto` cmdline client.
5
6The use of `--detach` and `--attach` is highly discouraged because of the risk
7of leaking tracing sessions and accidentally leaving tracing on for arbitrarily
8long periods of time.
9
10If what you are looking for is just a way to grab a trace in background (e.g.,
11while the USB cable / adb is disconnected) from the adb shell simply use
12`--background`.
13
14Use case
15--------
16By default the tracing service `traced` keeps the lifetime of a tracing session
17attached to the lifetime of the `perfetto` cmdline client that started it.
18This means that a `killall perfetto` or `kill $PID_OF_PERFETTO` is sufficient
19to guarantee that the tracing session is stopped.
20There are rare occasions when this is undesirable.
21
22The use case this has been designed for is the Traceur app (on-device tracing
23UI for Android).
24When required by the user, Traceur needs to enable tracing in the background,
25possibly for very long periods of time.
26Because Traceur is not a persistent service (and even if it was, it could be
27still low-memory-killed), it cannot just use `--background`. This is
28because the Android framework kills any other process in the same process group
29when tearing down an app/service, and this would including killing forked
30`perfetto` client obtained via `--background`.
31
32Operation
33---------
34`--detach=key` decouples the lifetime of the cmdline client from the lifetime
35of the tracing session.
36
37The `key` argument is an arbitrary string passed by the client to later
38re-identify the session using `--attach=key`.
39
40Once detached, the cmdline client will exit (without forking any bg process) and
41the `traced` service will keep the tracing session alive.
42Because of the exit, a client that wants to use `--detach` needs to set the
43[`write_into_file`](long-traces.md) flag in the trace config, which transfers
44the output trace file descriptor to the service (see the [examples](#examples)
45section).
46
47A detached session will run until either:
48
49- The session is later re-attached and stopped.
50- The time limit specified by the `duration_ms` argument in the trace config
51  is reached.
52
53`--attach=key` re-couples the lifetime of a new cmdline client invocation with
54an existing tracing session identified by `key`.
55For security reasons the service allows a client to re-attach to a tracing
56session only if the Unix UID of the re-attaching client matches the UID of the
57client that originally started the session and detached.
58
59Overall `--attach=key` makes the `perfetto` cmdline client behave as if it was
60never detached. This means that:
61
62- sending a `SIGKILL` (or Ctrl-C) to the client will gracefully stop the tracing
63  session.
64- If the `duration_ms` time limit is hit, the client will be informed by the
65  service and exit soon after.
66
67When re-attaching it is possible to also specify a further `--stop` argument.
68`--stop` will gracefully terminate the tracing session immediately after
69re-attaching (This is to avoid a race where SIGKILL is sent too early, before
70the client gets a chance to attach or even register the signal handler).
71
72No other cmdline argument other than `--stop` can be passed when using
73`--attach`.
74
75`--is_detached=key` can be used to check whether a detached session is running.
76The cmdline client will return quickly after the invocation with the following
77exit code:
78
79- 0 if the session identified by `key` exists and can be re-attached.
80- 1 in case of a general error (e.g. wrong cmdline, cannot reach the service).
81- 2 if no detached session with the given `key` is found.
82
83Examples
84--------
85
86### Capturing a long trace in detached mode
87
88```bash
89echo '
90write_into_file: true
91# Long tracing mode, periodically flush the trace buffer into the trace file.
92file_write_period_ms: 5000
93
94buffers {
95  # This buffer needs to be big enough just to hold data between two consecutive
96  # |file_write_period|s (5s in this examples).
97  size_kb: 16384
98}
99
100data_sources {
101  config {
102    name: "linux.ftrace"
103    ftrace_config {
104      ftrace_events: "sched_switch"
105    }
106  }
107}
108' | perfetto -c - --txt --detach=session1 -o /data/misc/perfetto-traces/trace
109
110sleep 60
111
112perfetto --attach=session1 --stop
113# At this point the trace file is fully flushed into
114# /data/misc/perfetto-traces/trace.
115```
116
117### Start in detached ring-buffer mode. Later stop and save the ring buffer
118
119```bash
120echo '
121write_into_file: true
122
123# Specify an arbitrarily long flush period. Practically this means: never flush
124# unless trace is stopped.
125# TODO(primiano): an explicit no_periodic_flushes argument would be nicer. Maybe
126# we could repurpose the 0 value?
127file_write_period_ms: 1000000000
128
129buffers {
130  # This will be the size of the final trace.
131  size_kb: 16384
132}
133
134data_sources {
135  config {
136    name: "linux.ftrace"
137    ftrace_config {
138      ftrace_events: "sched_switch"
139    }
140  }
141}
142' | perfetto -c - --txt --detach=session2 -o /data/misc/perfetto-traces/trace
143
144# Wait for user input, or some critical event to happen.
145
146perfetto --attach=session2 --stop
147
148# At this point the trace file is saved into
149# /data/misc/perfetto-traces/trace.
150```
151
152### Start tracing with a time limit. Later re-attach and wait for the end
153
154```bash
155echo '
156duration_ms: 10000
157write_into_file: true
158
159buffers {
160  size_kb: 16384
161}
162
163data_sources {
164  config {
165    name: "linux.ftrace"
166    ftrace_config {
167      ftrace_events: "sched_switch"
168    }
169  }
170}
171' | perfetto -c - --txt --detach=session3 -o /data/misc/perfetto-traces/trace
172
173sleep 3
174perfetto --attach=session3
175# The cmdline client will stay up for 7 more seconds and then terminate.
176```
177