aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniele Di Proietto <ddiproietto@google.com>2021-10-04 13:20:48 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2021-10-04 13:20:48 +0000
commit7a5fa7367eb87fb1901c7bac8937b6c95e832fe8 (patch)
tree6b07719b8c72c3d71f04d7e90dda1f723787d7bf
parent588a25f21493f66fd214ae473a4c2bcfb8980f8f (diff)
parente84bb9e7a07d27a654dbfa000080df50d499d191 (diff)
downloadperfetto-7a5fa7367eb87fb1901c7bac8937b6c95e832fe8.tar.gz
Merge "perfetto.rc: Support boot tracing in android"
-rw-r--r--docs/case-studies/android-boot-tracing.md79
-rw-r--r--docs/toc.md1
-rw-r--r--perfetto.rc31
-rw-r--r--src/traced/service/service.cc12
4 files changed, 123 insertions, 0 deletions
diff --git a/docs/case-studies/android-boot-tracing.md b/docs/case-studies/android-boot-tracing.md
new file mode 100644
index 000000000..d45f55311
--- /dev/null
+++ b/docs/case-studies/android-boot-tracing.md
@@ -0,0 +1,79 @@
+# Recording traces on Android boot
+
+Since Android 13 (T), perfetto can be configured to automatically start
+recording traces on boot. This can be useful to profile the boot process.
+
+## Steps
+
+* Create a file with the desired [trace configuration](/docs/concepts/config.md)
+ in Text format (not binary). Example (more in [/test/configs/](/test/configs/)):
+ ```
+ # One buffer allocated within the central tracing binary for the entire trace,
+ # shared by the two data sources below.
+ buffers {
+ size_kb: 32768
+ fill_policy: DISCARD
+ }
+
+ # Ftrace data from the kernel, mainly the process scheduling events.
+ data_sources {
+ config {
+ name: "linux.ftrace"
+ target_buffer: 0
+ ftrace_config {
+ ftrace_events: "sched_switch"
+ ftrace_events: "sched_waking"
+ ftrace_events: "sched_wakeup_new"
+
+ ftrace_events: "task_newtask"
+ ftrace_events: "task_rename"
+
+ ftrace_events: "sched_process_exec"
+ ftrace_events: "sched_process_exit"
+ ftrace_events: "sched_process_fork"
+ ftrace_events: "sched_process_free"
+ ftrace_events: "sched_process_hang"
+ ftrace_events: "sched_process_wait"
+ }
+ }
+ }
+
+ # Resolve process commandlines and parent/child relationships, to better
+ # interpret the ftrace events, which are in terms of pids.
+ data_sources {
+ config {
+ name: "linux.process_stats"
+ target_buffer: 0
+ }
+ }
+
+ # 10s trace, but can be stopped prematurely via `adb shell pkill -u perfetto`.
+ duration_ms: 10000
+ ```
+* Put the file on the device at `/data/misc/perfetto-configs/boottrace.pbtxt`:
+ ```
+ adb push <yourfile> /data/misc/perfetto-configs/boottrace.pbtxt
+ ```
+* Enable the perfetto\_boottrace service:
+ ```
+ adb shell setprop persist.debug.perfetto.boottrace 1
+ ```
+ The property is reset on boot. In order to trace the next boot, the command
+ must be reissued.
+* Reboot the device.
+* The output trace will be written at
+ `/data/misc/perfetto-traces/boottrace.perfetto-trace`. The file will be
+ removed before a new trace is started.
+ ```
+ adb pull /data/misc/perfetto-traces/boottrace.perfetto-trace
+ ```
+ **N.B.:** The file will appear after the recording has stopped (be sure to set
+ `duration_ms` to a reasonable value in the config) or after the first
+ `flush_period_ms`.
+* `boottrace.perfetto-trace` can now be opened in
+ [ui.perfetto.dev](https://ui.perfetto.dev/)
+
+## Implementation details
+* The trace will start only after persistent properties are loaded, which
+ happens after /data has been mounted.
+* The command to start the trace is implemented as oneshot init service.
diff --git a/docs/toc.md b/docs/toc.md
index 565ee8df3..6ddd80917 100644
--- a/docs/toc.md
+++ b/docs/toc.md
@@ -8,6 +8,7 @@
* [Heap profiling](quickstart/heap-profiling.md)
* [Case studies](#)
+ * [Android boot tracing](case-studies/android-boot-tracing.md)
* [Debugging memory usage](case-studies/memory.md)
* [Data sources](#)
diff --git a/perfetto.rc b/perfetto.rc
index 55ff78f0d..5be77583d 100644
--- a/perfetto.rc
+++ b/perfetto.rc
@@ -90,3 +90,34 @@ on property:persist.mm_events.enabled=true && property:persist.traced.enable=1
on property:persist.mm_events.enabled=false
stop mm_events
+
+#############################################################################
+# perfetto_boottrace - Starts a perfetto trace on boot
+#############################################################################
+#
+# There are two separate actions (a trigger action and a start action) to make
+# sure that perfetto_boottrace is started only once on boot (otherwise, whenever
+# persist.debug.perfetto.boottrace=1 is set, perfetto_boottrace would start
+# immediately).
+#
+# persist.debug.perfetto.boottrace=1 can be manually set after boot (to record
+# a trace on the next reboot) and we don't want to immediately start a trace
+# when setting the debug property. So we turn "ro.persistent_properties.ready"
+# into a trigger, and then check whether we should start tracing when the
+# trigger fires.
+on perfetto_maybe_boottrace && property:persist.debug.perfetto.boottrace=1 && property:persist.traced.enable=1
+ setprop persist.debug.perfetto.boottrace ""
+ rm /data/misc/perfetto-traces/boottrace.perfetto-trace
+ # Set by traced after listen()ing on the consumer socket. Without this,
+ # perfetto could try to connect to traced before traced is ready to listen.
+ wait_for_prop sys.trace.traced_started 1
+ start perfetto_boottrace
+
+on property:ro.persistent_properties.ready=true
+ trigger perfetto_maybe_boottrace
+
+service perfetto_boottrace /system/bin/perfetto -c /data/misc/perfetto-configs/boottrace.pbtxt --txt -o /data/misc/perfetto-traces/boottrace.perfetto-trace
+ disabled
+ oneshot
+ user shell
+ group nobody
diff --git a/src/traced/service/service.cc b/src/traced/service/service.cc
index f0a6c4ac2..095941fb8 100644
--- a/src/traced/service/service.cc
+++ b/src/traced/service/service.cc
@@ -39,6 +39,10 @@
#include <unistd.h>
#endif
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+#include <sys/system_properties.h>
+#endif
+
namespace perfetto {
namespace {
#if defined(PERFETTO_SET_SOCKET_PERMISSIONS)
@@ -216,6 +220,14 @@ int PERFETTO_EXPORT_ENTRYPOINT ServiceMain(int argc, char** argv) {
PERFETTO_CHECK(base::CloseFile(notif_fd) == 0);
}
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+ // Notify init (perfetto.rc) that traced has been started. Used only by
+ // the perfetto_boottrace init service.
+ if (__system_property_set("sys.trace.traced_started", "1") != 0) {
+ PERFETTO_PLOG("Failed to set property sys.trace.traced_started");
+ }
+#endif
+
PERFETTO_ILOG("Started traced, listening on %s %s", GetProducerSocket(),
GetConsumerSocket());
task_runner.Run();