Skip to content

Support Perfetto trace recovery across device reboot - #6928

Open
safayat-google wants to merge 5 commits into
mainfrom
dev/safayat/reboot-trace
Open

Support Perfetto trace recovery across device reboot#6928
safayat-google wants to merge 5 commits into
mainfrom
dev/safayat/reboot-trace

Conversation

@safayat-google

Copy link
Copy Markdown
Member

Adds support for persistent traces to survive device reboots on Android.
When persist_trace_across_reboots is enabled in TraceConfig, Perfetto saves persistent trace files to disk and recovers/uploads them on the next boot via --upload-after-reboot.

Summary of changes:

  • Added persist_trace_across_reboots to TraceConfig and AfterRebootTraceEvent proto header to annotate recovered trace metadata.
  • Unlinks trace files upfront before processing in UploadPersistentTracesAfterReboot to prevent crash loops if parsing or upload fails.
  • Synchronizes status via traced.reboot_trace_status sysprop so new tracing sessions wait for active uploads to finish before starting.
  • Emits StatSD atoms for trace recovery (atom 66), timeouts (atom 67), and framework handoff (atom 51).
    Tested on a device and verified new perfetto_unittests

Bug: 382209797
Test: atest perfetto_unittests;

Bug: 382209797
Test: m -j100 perfetto_unittests
Flag: EXEMPT BUGFIX
Change-Id: Ib1e121976c90309cb34db0a09617f0fba0951a42
@github-actions

github-actions Bot commented Jul 31, 2026

Copy link
Copy Markdown

@safayat-google
safayat-google marked this pull request as ready for review August 5, 2026 19:23
@safayat-google
safayat-google requested a review from a team as a code owner August 5, 2026 19:23

@LalitMaganti LalitMaganti left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First pass through these changes. Overall looking in the right direction but some questions.

// Supported on: Android 26Q4+.
optional bool persist_trace_across_reboots = 49;

// If set to true, forces explicit buffer flushes prior to periodic write

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't this the default now? Why do we need this?


package perfetto.protos;

// TODO: or should we just reuse an existing an existing proto file?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be nice to use an existing file if possible.

"Copying persistent trace %s for write_into_file session %" PRIu64
" into bugreport path %s",
persistent_path.c_str(), it->tsid, out_path.c_str());
base::CopyFileContents(*fd_in, *fd_out);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this not be on a thread? This seems inconsistent with how clone works otherwise.

// 3:ts : Timed out
const char* kRebootTraceStatusProp = "traced.reboot_trace_status";
constexpr uint64_t kUploadWaitTimeoutNs =
5ULL * 60 * 1000 * 1000 * 1000; // 5 minutes

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems like a very large timeout on the surface. Is there some motivation? Maybe add a comment?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh is this the time to wait for boot? Feels this variable is misnamed...

// If property is set, but the persistent trace file STILL exists on disk,
// log error, unlink file, and crash.
if (base::FileExists(target_file_path)) {
PERFETTO_ELOG(

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need statsd attoms for any case like this...

WaitForPreviousRebootTraceUpload(clean_name, file_path.c_str());

// Unlink any pre-existing instance of this persistent trace file.
unlink(file_path.c_str());

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we did O_TRUNC in the flags below, wouldn't that be stricly better than unlink + open?

persistent_path.c_str(), it->tsid);
}
sync_fn();
continue;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this continue seems a bit off to me, if we hit then we'll never invoke CloneSessionOnThread below? I think we should not guard on basis of is_write_into_file.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants