|
57 | 57 | #include <log/log_read.h> |
58 | 58 | #include <math.h> |
59 | 59 | #include <openssl/sha.h> |
| 60 | +#include <perfetto_flags.h> |
60 | 61 | #include <poll.h> |
61 | 62 | #include <private/android_filesystem_config.h> |
62 | 63 | #include <private/android_logger.h> |
@@ -190,7 +191,7 @@ void add_mountinfo(); |
190 | 191 | #define SNAPSHOTCTL_LOG_DIR "/data/misc/snapshotctl_log" |
191 | 192 | #define LINKERCONFIG_DIR "/linkerconfig" |
192 | 193 | #define PACKAGE_DEX_USE_LIST "/data/system/package-dex-usage.list" |
193 | | -#define SYSTEM_TRACE_SNAPSHOT "/data/misc/perfetto-traces/bugreport/systrace.pftrace" |
| 194 | +#define SYSTEM_TRACE_DIR "/data/misc/perfetto-traces/bugreport" |
194 | 195 | #define CGROUPFS_DIR "/sys/fs/cgroup" |
195 | 196 | #define SDK_EXT_INFO "/apex/com.android.sdkext/bin/derive_sdk" |
196 | 197 | #define DROPBOX_DIR "/data/system/dropbox" |
@@ -359,6 +360,31 @@ static bool CopyFileToFile(const std::string& input_file, const std::string& out |
359 | 360 | return CopyFileToFd(input_file, out_fd.get()); |
360 | 361 | } |
361 | 362 |
|
| 363 | +template <typename Func> |
| 364 | +size_t ForEachTrace(Func func) { |
| 365 | + std::unique_ptr<DIR, decltype(&closedir)> traces_dir(opendir(SYSTEM_TRACE_DIR), closedir); |
| 366 | + |
| 367 | + if (traces_dir == nullptr) { |
| 368 | + MYLOGW("Unable to open directory %s: %s\n", SYSTEM_TRACE_DIR, strerror(errno)); |
| 369 | + return 0; |
| 370 | + } |
| 371 | + |
| 372 | + size_t traces_found = 0; |
| 373 | + struct dirent* entry = nullptr; |
| 374 | + while ((entry = readdir(traces_dir.get()))) { |
| 375 | + if (entry->d_type != DT_REG) { |
| 376 | + continue; |
| 377 | + } |
| 378 | + std::string trace_path = std::string(SYSTEM_TRACE_DIR) + "/" + entry->d_name; |
| 379 | + if (access(trace_path.c_str(), F_OK) != 0) { |
| 380 | + continue; |
| 381 | + } |
| 382 | + ++traces_found; |
| 383 | + func(trace_path); |
| 384 | + } |
| 385 | + return traces_found; |
| 386 | +} |
| 387 | + |
362 | 388 | } // namespace |
363 | 389 | } // namespace os |
364 | 390 | } // namespace android |
@@ -1101,20 +1127,16 @@ static void MaybeAddSystemTraceToZip() { |
1101 | 1127 | // This function copies into the .zip the system trace that was snapshotted |
1102 | 1128 | // by the early call to MaybeSnapshotSystemTraceAsync(), if any background |
1103 | 1129 | // tracing was happening. |
1104 | | - bool system_trace_exists = access(SYSTEM_TRACE_SNAPSHOT, F_OK) == 0; |
1105 | | - if (!system_trace_exists) { |
1106 | | - // No background trace was happening at the time MaybeSnapshotSystemTraceAsync() was invoked |
1107 | | - if (!PropertiesHelper::IsUserBuild()) { |
1108 | | - MYLOGI( |
1109 | | - "No system traces found. Check for previously uploaded traces by looking for " |
1110 | | - "go/trace-uuid in logcat") |
1111 | | - } |
1112 | | - return; |
| 1130 | + size_t traces_found = android::os::ForEachTrace([&](const std::string& trace_path) { |
| 1131 | + ds.AddZipEntry(ZIP_ROOT_DIR + trace_path, trace_path); |
| 1132 | + android::os::UnlinkAndLogOnError(trace_path); |
| 1133 | + }); |
| 1134 | + |
| 1135 | + if (traces_found == 0 && !PropertiesHelper::IsUserBuild()) { |
| 1136 | + MYLOGI( |
| 1137 | + "No system traces found. Check for previously uploaded traces by looking for " |
| 1138 | + "go/trace-uuid in logcat") |
1113 | 1139 | } |
1114 | | - ds.AddZipEntry( |
1115 | | - ZIP_ROOT_DIR + SYSTEM_TRACE_SNAPSHOT, |
1116 | | - SYSTEM_TRACE_SNAPSHOT); |
1117 | | - android::os::UnlinkAndLogOnError(SYSTEM_TRACE_SNAPSHOT); |
1118 | 1140 | } |
1119 | 1141 |
|
1120 | 1142 | static void DumpVisibleWindowViews() { |
@@ -3412,8 +3434,8 @@ Dumpstate::RunStatus Dumpstate::RunInternal(int32_t calling_uid, |
3412 | 3434 | // duration is logged into MYLOG instead. |
3413 | 3435 | PrintHeader(); |
3414 | 3436 |
|
3415 | | - bool system_trace_exists = access(SYSTEM_TRACE_SNAPSHOT, F_OK) == 0; |
3416 | | - if (options_->use_predumped_ui_data && !system_trace_exists) { |
| 3437 | + size_t trace_count = android::os::ForEachTrace([](const std::string&) {}); |
| 3438 | + if (options_->use_predumped_ui_data && trace_count == 0) { |
3417 | 3439 | MYLOGW("Ignoring 'use predumped data' flag because no predumped data is available"); |
3418 | 3440 | options_->use_predumped_ui_data = false; |
3419 | 3441 | } |
@@ -3560,20 +3582,24 @@ std::future<std::string> Dumpstate::MaybeSnapshotSystemTraceAsync() { |
3560 | 3582 | } |
3561 | 3583 |
|
3562 | 3584 | // If a stale file exists already, remove it. |
3563 | | - unlink(SYSTEM_TRACE_SNAPSHOT); |
| 3585 | + android::os::ForEachTrace([&](const std::string& trace_path) { unlink(trace_path.c_str()); }); |
3564 | 3586 |
|
3565 | 3587 | MYLOGI("Launching async '%s'", SERIALIZE_PERFETTO_TRACE_TASK.c_str()) |
| 3588 | + |
3566 | 3589 | return std::async( |
3567 | 3590 | std::launch::async, [this, outPath = std::move(outPath), outFd = std::move(outFd)] { |
3568 | | - // If a background system trace is happening and is marked as "suitable for |
3569 | | - // bugreport" (i.e. bugreport_score > 0 in the trace config), this command |
3570 | | - // will stop it and serialize into SYSTEM_TRACE_SNAPSHOT. In the (likely) |
3571 | | - // case that no trace is ongoing, this command is a no-op. |
| 3591 | + // If one or more background system traces are happening and are marked as |
| 3592 | + // "suitable for bugreport" (bugreport_score > 0 in the trace config), this command |
| 3593 | + // will snapshot them into SYSTEM_TRACE_DIR. |
| 3594 | + // In the (likely) case that no trace is ongoing, this command is a no-op. |
3572 | 3595 | // Note: this should not be enqueued as we need to freeze the trace before |
3573 | 3596 | // dumpstate starts. Otherwise the trace ring buffers will contain mostly |
3574 | 3597 | // the dumpstate's own activity which is irrelevant. |
| 3598 | + const char* cmd_arg = perfetto::flags::save_all_traces_in_bugreport() |
| 3599 | + ? "--save-all-for-bugreport" |
| 3600 | + : "--save-for-bugreport"; |
3575 | 3601 | RunCommand( |
3576 | | - SERIALIZE_PERFETTO_TRACE_TASK, {"perfetto", "--save-for-bugreport"}, |
| 3602 | + SERIALIZE_PERFETTO_TRACE_TASK, {"perfetto", cmd_arg}, |
3577 | 3603 | CommandOptions::WithTimeout(30).DropRoot().CloseAllFileDescriptorsOnExec().Build(), |
3578 | 3604 | false, outFd); |
3579 | 3605 | // MaybeAddSystemTraceToZip() will take care of copying the trace in the zip |
|
0 commit comments