Snap for 7483611 from 15cf3b63e688a8c14e0aa5989c69fe4fcfb3f027 to mainline-documentsui-release
Change-Id: I37cc925cd22b17c1e1bc64edd07f6225119d6e71
diff --git a/include/perfetto/ext/tracing/core/tracing_service.h b/include/perfetto/ext/tracing/core/tracing_service.h
index 20382a1..db54dbb 100644
--- a/include/perfetto/ext/tracing/core/tracing_service.h
+++ b/include/perfetto/ext/tracing/core/tracing_service.h
@@ -42,7 +42,7 @@
class TraceWriter;
// Exposed for testing.
-extern const char* kBugreportTracePath;
+std::string GetBugreportPath();
// TODO: for the moment this assumes that all the calls happen on the same
// thread/sequence. Not sure this will be the case long term in Chrome.
diff --git a/protos/perfetto/ipc/consumer_port.proto b/protos/perfetto/ipc/consumer_port.proto
index 41242e7..9f6d533 100644
--- a/protos/perfetto/ipc/consumer_port.proto
+++ b/protos/perfetto/ipc/consumer_port.proto
@@ -261,7 +261,7 @@
// or something failed.
message SaveTraceForBugreportResponse {
// If true, an eligible the trace was saved into a known location (on Android
- // /data/misc/perfetto-traces, see kBugreportTracePath).
+ // /data/misc/perfetto-traces, see GetBugreportPath()).
// If false no trace with bugreport_score > 0 was found or an error occurred.
// see |msg| in that case for details about the failure.
optional bool success = 1;
diff --git a/src/perfetto_cmd/perfetto_cmd.cc b/src/perfetto_cmd/perfetto_cmd.cc
index 526139d..449f1f5 100644
--- a/src/perfetto_cmd/perfetto_cmd.cc
+++ b/src/perfetto_cmd/perfetto_cmd.cc
@@ -903,10 +903,6 @@
}
if (save_to_incidentd_) {
- if (!uuid_.empty()) {
- base::Uuid uuid(uuid_);
- PERFETTO_LOG("go/trace-uuid/%s", uuid.ToPrettyString().c_str());
- }
#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
SaveTraceIntoDropboxAndIncidentOrCrash();
#endif
diff --git a/src/perfetto_cmd/perfetto_cmd_android.cc b/src/perfetto_cmd/perfetto_cmd_android.cc
index fe2572c..d64fe85 100644
--- a/src/perfetto_cmd/perfetto_cmd_android.cc
+++ b/src/perfetto_cmd/perfetto_cmd_android.cc
@@ -48,6 +48,12 @@
// Save the trace as an incident.
SaveOutputToIncidentTraceOrCrash();
+ if (!uuid_.empty()) {
+ base::Uuid uuid(uuid_);
+ PERFETTO_LOG("go/trace-uuid/%s (%" PRIu64 " bytes)",
+ uuid.ToPrettyString().c_str(), bytes_written_);
+ }
+
// Ask incidentd to create a report, which will read the file we just
// wrote.
const auto& cfg = trace_config_->incident_report_config();
diff --git a/src/tracing/core/tracing_service_impl.cc b/src/tracing/core/tracing_service_impl.cc
index 7084dec..1764a0b 100644
--- a/src/tracing/core/tracing_service_impl.cc
+++ b/src/tracing/core/tracing_service_impl.cc
@@ -56,6 +56,7 @@
#include "perfetto/ext/base/file_utils.h"
#include "perfetto/ext/base/metatrace.h"
#include "perfetto/ext/base/string_utils.h"
+#include "perfetto/ext/base/temp_file.h"
#include "perfetto/ext/base/utils.h"
#include "perfetto/ext/base/watchdog.h"
#include "perfetto/ext/tracing/core/basic_types.h"
@@ -100,16 +101,11 @@
#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) && \
PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)
-// This is the only SELinux approved dir for trace files that are created
+// These are the only SELinux approved dir for trace files that are created
// directly by traced.
const char* kTraceDirBasePath = "/data/misc/perfetto-traces/";
-#endif
-
-#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
-const char* kBugreportTracePath =
+const char* kAndroidProductionBugreportTracePath =
"/data/misc/perfetto-traces/bugreport/systrace.pftrace";
-#else
-const char* kBugreportTracePath = "/tmp/bugreport.pftrace";
#endif
namespace {
@@ -273,7 +269,7 @@
}
std::string GetBugreportTmpPath() {
- return std::string(kBugreportTracePath) + ".tmp";
+ return GetBugreportPath() + ".tmp";
}
bool ShouldLogEvent(const TraceConfig& cfg) {
@@ -299,6 +295,16 @@
constexpr uint32_t TracingServiceImpl::kDataSourceStopTimeoutMs;
constexpr uint8_t TracingServiceImpl::kSyncMarker[];
+std::string GetBugreportPath() {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) && \
+ PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)
+ return kAndroidProductionBugreportTracePath;
+#else
+ // Only for tests, SaveTraceForBugreport is not used on other OSes.
+ return base::GetSysTempDir() + "/bugreport.pftrace";
+#endif
+}
+
// static
std::unique_ptr<TracingService> TracingService::CreateInstance(
std::unique_ptr<SharedMemory::Factory> shm_factory,
@@ -1808,8 +1814,9 @@
PERFETTO_DLOG("Triggering final flush for %" PRIu64, tsid);
auto weak_this = weak_ptr_factory_.GetWeakPtr();
Flush(tsid, 0, [weak_this, tsid](bool success) {
- PERFETTO_DLOG("Flush done (success: %d), disabling trace session %" PRIu64,
- success, tsid);
+ // This was a DLOG up to Jun 2021 (v16, Android S).
+ PERFETTO_LOG("FlushAndDisableTracing(%" PRIu64 ") done, success=%d", tsid,
+ success);
if (!weak_this)
return;
TracingSession* session = weak_this->GetTracingSession(tsid);
@@ -1925,7 +1932,8 @@
// packets like TraceConfig and Clock snapshots. So we bail out early and let
// the consumer know there is no data.
if (!tracing_session->config.trigger_config().triggers().empty() &&
- tracing_session->received_triggers.empty()) {
+ tracing_session->received_triggers.empty() &&
+ !tracing_session->seized_for_bugreport) {
PERFETTO_DLOG(
"ReadBuffers(): tracing session has not received a trigger yet.");
return false;
@@ -3173,6 +3181,12 @@
if (!max_session)
return false;
+ PERFETTO_LOG("Seizing trace for bugreport. tsid:%" PRIu64
+ " state:%d wf:%d score:%d name:\"%s\"",
+ max_tsid, max_session->state, !!max_session->write_into_file,
+ max_session->config.bugreport_score(),
+ max_session->config.unique_session_name().c_str());
+
auto br_fd = CreateTraceFile(GetBugreportTmpPath(), /*overwrite=*/true);
if (!br_fd)
return false;
@@ -3521,12 +3535,12 @@
SaveTraceForBugreportCallback consumer_callback) {
PERFETTO_DCHECK_THREAD(thread_checker_);
auto on_complete_callback = [consumer_callback] {
- if (rename(GetBugreportTmpPath().c_str(), kBugreportTracePath)) {
+ if (rename(GetBugreportTmpPath().c_str(), GetBugreportPath().c_str())) {
consumer_callback(false, "rename(" + GetBugreportTmpPath() + ", " +
- kBugreportTracePath + ") failed (" +
+ GetBugreportPath() + ") failed (" +
strerror(errno) + ")");
} else {
- consumer_callback(true, kBugreportTracePath);
+ consumer_callback(true, GetBugreportPath());
}
};
if (!service_->MaybeSaveTraceForBugreport(std::move(on_complete_callback))) {
diff --git a/test/end_to_end_integrationtest.cc b/test/end_to_end_integrationtest.cc
index 64a7c80..6333641 100644
--- a/test/end_to_end_integrationtest.cc
+++ b/test/end_to_end_integrationtest.cc
@@ -270,7 +270,7 @@
// Read the trace written in the fixed location (/data/misc/perfetto-traces/
// on Android, /tmp/ on Linux/Mac) and make sure it has the right contents.
std::string trace_str;
- base::ReadFile(kBugreportTracePath, &trace_str);
+ base::ReadFile(GetBugreportPath(), &trace_str);
ASSERT_FALSE(trace_str.empty());
protos::gen::Trace trace;
ASSERT_TRUE(trace.ParseFromString(trace_str));
@@ -1076,6 +1076,47 @@
}
}
+// Tests that SaveTraceForBugreport() works also if the trace has triggers
+// defined and those triggers have not been hit. This is a regression test for
+// b/188008375 .
+TEST_F(PerfettoTest, SaveForBugreport_Triggers) {
+ base::TestTaskRunner task_runner;
+
+ TestHelper helper(&task_runner);
+ helper.StartServiceIfRequired();
+ helper.ConnectFakeProducer();
+ helper.ConnectConsumer();
+ helper.WaitForConsumerConnect();
+
+ TraceConfig trace_config;
+ SetTraceConfigForBugreportTest(&trace_config);
+ trace_config.set_duration_ms(0); // set_trigger_timeout_ms is used instead.
+ auto* trigger_config = trace_config.mutable_trigger_config();
+ trigger_config->set_trigger_timeout_ms(8.64e+7);
+ trigger_config->set_trigger_mode(TraceConfig::TriggerConfig::STOP_TRACING);
+ auto* trigger = trigger_config->add_triggers();
+ trigger->set_name("trigger_name");
+ trigger->set_stop_delay_ms(1);
+
+ helper.StartTracing(trace_config);
+ helper.WaitForProducerEnabled();
+
+ EXPECT_TRUE(helper.SaveTraceForBugreportAndWait());
+ helper.WaitForTracingDisabled();
+
+ VerifyBugreportTraceContents();
+
+ // Now read the original trace.
+ helper.ReadData();
+ helper.WaitForReadData();
+ const auto& packets = helper.full_trace();
+ ASSERT_EQ(packets.size(), 1u);
+ for (const auto& p : packets) {
+ ASSERT_TRUE(p.has_service_event());
+ ASSERT_TRUE(p.service_event().seized_for_bugreport());
+ }
+}
+
// Disable cmdline tests on sanitizets because they use fork() and that messes
// up leak / races detections, which has been fixed only recently (see
// https://github.com/google/sanitizers/issues/836 ).