summaryrefslogtreecommitdiff
path: root/chromium/services/tracing/public/cpp/perfetto
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2020-10-12 14:27:29 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2020-10-13 09:35:20 +0000
commitc30a6232df03e1efbd9f3b226777b07e087a1122 (patch)
treee992f45784689f373bcc38d1b79a239ebe17ee23 /chromium/services/tracing/public/cpp/perfetto
parent7b5b123ac58f58ffde0f4f6e488bcd09aa4decd3 (diff)
downloadqtwebengine-chromium-85-based.tar.gz
BASELINE: Update Chromium to 85.0.4183.14085-based
Change-Id: Iaa42f4680837c57725b1344f108c0196741f6057 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/services/tracing/public/cpp/perfetto')
-rw-r--r--chromium/services/tracing/public/cpp/perfetto/macros.h73
-rw-r--r--chromium/services/tracing/public/cpp/perfetto/macros_internal.cc61
-rw-r--r--chromium/services/tracing/public/cpp/perfetto/macros_internal.h213
-rw-r--r--chromium/services/tracing/public/cpp/perfetto/perfetto_config.cc149
-rw-r--r--chromium/services/tracing/public/cpp/perfetto/perfetto_config.h13
-rw-r--r--chromium/services/tracing/public/cpp/perfetto/posix_system_producer.cc8
-rw-r--r--chromium/services/tracing/public/cpp/perfetto/producer_client.cc46
-rw-r--r--chromium/services/tracing/public/cpp/perfetto/producer_client.h14
-rw-r--r--chromium/services/tracing/public/cpp/perfetto/producer_test_utils.cc161
-rw-r--r--chromium/services/tracing/public/cpp/perfetto/producer_test_utils.h94
-rw-r--r--chromium/services/tracing/public/cpp/perfetto/system_trace_writer.h2
-rw-r--r--chromium/services/tracing/public/cpp/perfetto/trace_event_data_source.cc61
-rw-r--r--chromium/services/tracing/public/cpp/perfetto/trace_event_data_source.h36
-rw-r--r--chromium/services/tracing/public/cpp/perfetto/trace_event_data_source_unittest.cc204
-rw-r--r--chromium/services/tracing/public/cpp/perfetto/trace_time.h12
-rw-r--r--chromium/services/tracing/public/cpp/perfetto/track_event_thread_local_event_sink.cc75
-rw-r--r--chromium/services/tracing/public/cpp/perfetto/track_event_thread_local_event_sink.h82
17 files changed, 588 insertions, 716 deletions
diff --git a/chromium/services/tracing/public/cpp/perfetto/macros.h b/chromium/services/tracing/public/cpp/perfetto/macros.h
index c7c461a27a1..ade79860aa4 100644
--- a/chromium/services/tracing/public/cpp/perfetto/macros.h
+++ b/chromium/services/tracing/public/cpp/perfetto/macros.h
@@ -5,76 +5,7 @@
#ifndef SERVICES_TRACING_PUBLIC_CPP_PERFETTO_MACROS_H_
#define SERVICES_TRACING_PUBLIC_CPP_PERFETTO_MACROS_H_
-#include "base/trace_event/trace_event.h"
-#include "services/tracing/public/cpp/perfetto/macros_internal.h"
-
-// Needed not for this file but for every user of the TRACE_EVENT macros for the
-// lambda definition. So included here for convenience.
-#include "third_party/perfetto/include/perfetto/tracing/event_context.h"
-#include "third_party/perfetto/protos/perfetto/trace/track_event/track_event.pbzero.h"
-
-#if defined(TRACE_EVENT_BEGIN)
-#error "Another copy of perfetto tracing macros have been included"
-#endif
-
-// TODO(nuskos): This whole file should be removed and migrated to using the
-// Perfetto client library macros. However currently chromium isn't set up to
-// use the client library so in the meantime we've added support for features we
-// want sooner.
-
-namespace tracing {
-// The perfetto client library does not use event names for
-// TRACE_EVENT_PHASE_END. However currently Chrome expects all TraceEvents to
-// have event names. So until we move over to the client library we will use
-// this for all TRACE_EVENT_PHASE_END typed arguments.
-//
-// TODO(nuskos): remove this constant.
-constexpr char kTraceEventEndName[] = "";
-} // namespace tracing
-
-// Begin a thread-scoped slice under |category| with the title |name|. Both
-// strings must be static constants. The track event is only recorded if
-// |category| is enabled for a tracing session.
-//
-// Rest of parameters can contain: a perfetto::Track object for asynchronous
-// events and a lambda used to fill typed event. Should be passed in that exact
-// order when both are used.
-//
-// When lambda is passed as an argument, it is executed synchronously.
-//
-// TODO(nuskos): Give a simple example once we have a typed event that doesn't
-// need interning.
-// TRACE_EVENT_BEGIN("log", "LogMessage",
-// [](perfetto::EventContext ctx) {
-// auto* event = ctx.event();
-// // Fill in some field in track_event.
-// });
-#define TRACE_EVENT_BEGIN(category, name, ...) \
- TRACING_INTERNAL_ADD_TRACE_EVENT(TRACE_EVENT_PHASE_BEGIN, category, name, \
- TRACE_EVENT_FLAG_NONE, ##__VA_ARGS__)
-
-// End a thread-scoped slice under |category|.
-#define TRACE_EVENT_END(category, ...) \
- TRACING_INTERNAL_ADD_TRACE_EVENT(TRACE_EVENT_PHASE_END, category, \
- tracing::kTraceEventEndName, \
- TRACE_EVENT_FLAG_NONE, ##__VA_ARGS__)
-
-// Begin a thread-scoped slice which gets automatically closed when going out
-// of scope.
-//
-// BEWARE: similarly to TRACE_EVENT_BEGIN, this macro does accept a track, but
-// it does not work properly and should not be used.
-// TODO(b/154583431): figure out how to fix or disallow that and update the
-// comment.
-//
-// Similarly to TRACE_EVENT_BEGIN, when lambda is passed as an argument, it is
-// executed synchronously.
-#define TRACE_EVENT(category, name, ...) \
- TRACING_INTERNAL_SCOPED_ADD_TRACE_EVENT(category, name, ##__VA_ARGS__)
-
-// Emit a single event called "name" immediately, with zero duration.
-#define TRACE_EVENT_INSTANT(category, name, scope, ...) \
- TRACING_INTERNAL_ADD_TRACE_EVENT(TRACE_EVENT_PHASE_INSTANT, category, name, \
- scope, ##__VA_ARGS__)
+// TODO(eseckler): Replace this header with the version from base.
+#include "base/trace_event/typed_macros.h"
#endif // SERVICES_TRACING_PUBLIC_CPP_PERFETTO_MACROS_H_
diff --git a/chromium/services/tracing/public/cpp/perfetto/macros_internal.cc b/chromium/services/tracing/public/cpp/perfetto/macros_internal.cc
deleted file mode 100644
index 8efeeda4476..00000000000
--- a/chromium/services/tracing/public/cpp/perfetto/macros_internal.cc
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "services/tracing/public/cpp/perfetto/macros_internal.h"
-
-#include "base/trace_event/thread_instruction_count.h"
-
-namespace tracing {
-namespace internal {
-namespace {
-
-base::ThreadTicks ThreadNow() {
- return base::ThreadTicks::IsSupported()
- ? base::subtle::ThreadTicksNowIgnoringOverride()
- : base::ThreadTicks();
-}
-
-base::trace_event::ThreadInstructionCount ThreadInstructionNow() {
- return base::trace_event::ThreadInstructionCount::IsSupported()
- ? base::trace_event::ThreadInstructionCount::Now()
- : base::trace_event::ThreadInstructionCount();
-}
-
-} // namespace
-
-base::Optional<base::trace_event::TraceEvent> CreateTraceEvent(
- char phase,
- const unsigned char* category_group_enabled,
- const char* name,
- unsigned int flags,
- base::TimeTicks ts = base::TimeTicks()) {
- DCHECK(phase == TRACE_EVENT_PHASE_BEGIN || phase == TRACE_EVENT_PHASE_END ||
- phase == TRACE_EVENT_PHASE_INSTANT);
- DCHECK(category_group_enabled);
- const int thread_id = static_cast<int>(base::PlatformThread::CurrentId());
- auto* trace_log = base::trace_event::TraceLog::GetInstance();
- DCHECK(trace_log);
- if (!trace_log->ShouldAddAfterUpdatingState(phase, category_group_enabled,
- name, trace_event_internal::kNoId,
- thread_id, nullptr)) {
- return base::nullopt;
- }
-
- if (ts.is_null()) {
- ts = TRACE_TIME_TICKS_NOW();
- } else {
- flags |= TRACE_EVENT_FLAG_EXPLICIT_TIMESTAMP;
- }
- base::ThreadTicks thread_now = ThreadNow();
- base::trace_event::ThreadInstructionCount thread_instruction_now =
- ThreadInstructionNow();
-
- return base::trace_event::TraceEvent(
- thread_id, ts, thread_now, thread_instruction_now, phase,
- category_group_enabled, name, trace_event_internal::kGlobalScope,
- trace_event_internal::kNoId, trace_event_internal::kNoId, nullptr, flags);
-}
-
-} // namespace internal
-} // namespace tracing
diff --git a/chromium/services/tracing/public/cpp/perfetto/macros_internal.h b/chromium/services/tracing/public/cpp/perfetto/macros_internal.h
deleted file mode 100644
index f2401f51eb9..00000000000
--- a/chromium/services/tracing/public/cpp/perfetto/macros_internal.h
+++ /dev/null
@@ -1,213 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef SERVICES_TRACING_PUBLIC_CPP_PERFETTO_MACROS_INTERNAL_H_
-#define SERVICES_TRACING_PUBLIC_CPP_PERFETTO_MACROS_INTERNAL_H_
-
-#include "build/build_config.h"
-#include "third_party/perfetto/include/perfetto/tracing/event_context.h"
-#include "third_party/perfetto/include/perfetto/tracing/track.h"
-
-// Copy of function with the same name from Perfetto client library.
-template <typename T>
-static constexpr bool IsValidTraceLambdaImpl(
- typename std::enable_if<static_cast<bool>(
- sizeof(std::declval<T>()(std::declval<perfetto::EventContext>()),
- 0))>::type* = nullptr) {
- return true;
-}
-
-template <typename T>
-static constexpr bool IsValidTraceLambdaImpl(...) {
- return false;
-}
-
-template <typename T>
-static constexpr bool IsValidTraceLambda() {
- return IsValidTraceLambdaImpl<T>(nullptr);
-}
-
-#if !defined(OS_IOS) && !defined(OS_NACL)
-
-#include "base/component_export.h"
-#include "base/trace_event/trace_event.h"
-#include "services/tracing/public/cpp/perfetto/trace_event_data_source.h"
-
-namespace tracing {
-namespace internal {
-base::Optional<base::trace_event::TraceEvent> COMPONENT_EXPORT(TRACING_CPP)
- CreateTraceEvent(char phase,
- const unsigned char* category_group_enabled,
- const char* name,
- unsigned int flags,
- base::TimeTicks timestamp);
-
-template <
- typename TrackEventArgumentFunction = void (*)(perfetto::EventContext),
- typename ArgumentFunctionCheck = typename std::enable_if<
- IsValidTraceLambda<TrackEventArgumentFunction>()>::type>
-static inline base::trace_event::TraceEventHandle AddTraceEvent(
- char phase,
- const unsigned char* category_group_enabled,
- const char* name,
- unsigned int flags,
- const perfetto::Track& track,
- base::TimeTicks timestamp,
- TrackEventArgumentFunction argument_func) {
- base::trace_event::TraceEventHandle handle = {0, 0, 0};
- auto maybe_event =
- CreateTraceEvent(phase, category_group_enabled, name, flags, timestamp);
- if (!maybe_event) {
- return handle;
- }
- TraceEventDataSource::OnAddTraceEvent(&maybe_event.value(),
- /* thread_will_flush = */ false,
- nullptr, track,
- std::move(argument_func));
- return handle;
-}
-
-} // namespace internal
-} // namespace tracing
-
-// These macros should not be called directly. They are intended to be used by
-// macros in //services/tracing/perfetto/macros.h only.
-
-#define TRACING_INTERNAL_CONCAT2(a, b) a##b
-#define TRACING_INTERNAL_CONCAT(a, b) TRACING_INTERNAL_CONCAT2(a, b)
-#define TRACING_INTERNAL_UID(prefix) TRACING_INTERNAL_CONCAT(prefix, __LINE__)
-
-#define TRACING_INTERNAL_ADD_TRACE_EVENT(phase, category, name, flags, ...) \
- do { \
- INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category); \
- if (INTERNAL_TRACE_EVENT_CATEGORY_GROUP_ENABLED()) { \
- tracing::internal::AddTraceEvent( \
- phase, INTERNAL_TRACE_EVENT_UID(category_group_enabled), name, \
- flags, ##__VA_ARGS__); \
- } \
- } while (false)
-
-#define TRACING_INTERNAL_SCOPED_ADD_TRACE_EVENT(category, name, ...) \
- struct { \
- struct ScopedTraceEvent { \
- /* The parameter is an implementation detail. It allows the */ \
- /* anonymous struct to use aggregate initialization to invoke the */ \
- /* lambda to emit the begin event with the proper reference capture */ \
- /* for any TrackEventArgumentFunction in |__VA_ARGS__|. This is */ \
- /* required so that the scoped event is exactly ONE line and can't */ \
- /* escape the scope if used in a single line if statement. */ \
- ScopedTraceEvent(...) {} \
- ~ScopedTraceEvent() { \
- /* TODO(nuskos): Remove the empty string passed as the |name| */ \
- /* field. As described in macros.h we shouldn't need it in our */ \
- /* end state. */ \
- TRACING_INTERNAL_ADD_TRACE_EVENT(TRACE_EVENT_PHASE_END, category, "", \
- TRACE_EVENT_FLAG_NONE, \
- [](perfetto::EventContext) {}); \
- } \
- } event; \
- } TRACING_INTERNAL_UID(scoped_event){[&]() { \
- TRACING_INTERNAL_ADD_TRACE_EVENT(TRACE_EVENT_PHASE_BEGIN, category, name, \
- TRACE_EVENT_FLAG_NONE, ##__VA_ARGS__); \
- return 0; \
- }()};
-
-#else // !defined(OS_IOS) && !defined(OS_NACL)
-
-// Tracing isn't supported on IOS or NACL so we just black hole all the
-// parameters into a function that doesn't do anything. This ensures that no
-// warnings about unused parameters are generated.
-
-namespace tracing {
-namespace internal {
-template <
- typename TrackEventArgumentFunction = void (*)(perfetto::EventContext)>
-static inline base::trace_event::TraceEventHandle AddTraceEvent(
- char,
- const unsigned char*,
- const char*,
- unsigned int,
- const perfetto::Track&,
- base::TimeTicks,
- TrackEventArgumentFunction) {
- return {0, 0, 0};
-}
-
-} // namespace internal
-} // namespace tracing
-
-#define TRACING_INTERNAL_ADD_TRACE_EVENT(phase, category, name, flags, ...) \
- tracing::internal::AddTraceEvent(phase, nullptr, name, flags, ##__VA_ARGS__);
-
-#define TRACING_INTERNAL_SCOPED_ADD_TRACE_EVENT(category, name, ...) \
- TRACING_INTERNAL_ADD_TRACE_EVENT('B', category, name, TRACE_EVENT_FLAG_NONE, \
- ##__VA_ARGS__);
-#endif // else of !defined(OS_IOS) && !defined(OS_NACL)
-
-namespace tracing {
-namespace internal {
-
-template <
- typename TrackEventArgumentFunction = void (*)(perfetto::EventContext),
- typename ArgumentFunctionCheck = typename std::enable_if<
- IsValidTraceLambda<TrackEventArgumentFunction>()>::type,
- typename TrackType,
- typename TrackTypeCheck = typename std::enable_if<
- std::is_convertible<TrackType, perfetto::Track>::value>::type>
-static inline base::trace_event::TraceEventHandle AddTraceEvent(
- char phase,
- const unsigned char* category_group_enabled,
- const char* name,
- unsigned int flags,
- const TrackType& track,
- TrackEventArgumentFunction argument_func) {
- return AddTraceEvent(phase, category_group_enabled, name, flags, track,
- base::TimeTicks(), argument_func);
-}
-
-template <
- typename TrackEventArgumentFunction = void (*)(perfetto::EventContext),
- typename ArgumentFunctionCheck = typename std::enable_if<
- IsValidTraceLambda<TrackEventArgumentFunction>()>::type>
-static inline base::trace_event::TraceEventHandle AddTraceEvent(
- char phase,
- const unsigned char* category_group_enabled,
- const char* name,
- unsigned int flags,
- TrackEventArgumentFunction argument_func) {
- return AddTraceEvent(phase, category_group_enabled, name, flags,
- perfetto::Track(), base::TimeTicks(), argument_func);
-}
-
-template <typename TrackType,
- typename TrackTypeCheck = typename std::enable_if<
- std::is_convertible<TrackType, perfetto::Track>::value>::type>
-inline base::trace_event::TraceEventHandle AddTraceEvent(
- char phase,
- const unsigned char* category_group_enabled,
- const char* name,
- unsigned int flags,
- const TrackType& track) {
- return AddTraceEvent(phase, category_group_enabled, name, flags, track,
- base::TimeTicks(), [](perfetto::EventContext ctx) {});
-}
-
-template <typename TrackType,
- typename TrackTypeCheck = typename std::enable_if<
- std::is_convertible<TrackType, perfetto::Track>::value>::type>
-inline base::trace_event::TraceEventHandle AddTraceEvent(
- char phase,
- const unsigned char* category_group_enabled,
- const char* name,
- unsigned int flags,
- const TrackType& track,
- base::TimeTicks timestamp) {
- return AddTraceEvent(phase, category_group_enabled, name, flags, track,
- timestamp, [](perfetto::EventContext ctx) {});
-}
-
-} // namespace internal
-} // namespace tracing
-
-#endif // SERVICES_TRACING_PUBLIC_CPP_PERFETTO_MACROS_INTERNAL_H_
diff --git a/chromium/services/tracing/public/cpp/perfetto/perfetto_config.cc b/chromium/services/tracing/public/cpp/perfetto/perfetto_config.cc
index 8f0cce3e2c9..94edd835823 100644
--- a/chromium/services/tracing/public/cpp/perfetto/perfetto_config.cc
+++ b/chromium/services/tracing/public/cpp/perfetto/perfetto_config.cc
@@ -13,6 +13,7 @@
#include "base/trace_event/trace_event.h"
#include "build/build_config.h"
#include "build/chromecast_buildflags.h"
+#include "services/tracing/public/cpp/perfetto/trace_time.h"
#include "services/tracing/public/mojom/perfetto_service.mojom.h"
namespace tracing {
@@ -34,11 +35,98 @@ perfetto::TraceConfig::DataSource* AddDataSourceConfig(
return data_source;
}
+void AddDataSourceConfigs(
+ perfetto::TraceConfig* perfetto_config,
+ const base::trace_event::TraceConfig::ProcessFilterConfig& process_filters,
+ const base::trace_event::TraceConfig& stripped_config,
+ const std::set<std::string>& source_names,
+ bool privacy_filtering_enabled) {
+ const std::string chrome_config_string = stripped_config.ToString();
+
+ // Capture actual trace events.
+ if (source_names.empty() ||
+ source_names.count(tracing::mojom::kTraceEventDataSourceName) == 1) {
+ auto* trace_event_data_source = AddDataSourceConfig(
+ perfetto_config, tracing::mojom::kTraceEventDataSourceName,
+ chrome_config_string, privacy_filtering_enabled);
+ for (auto& enabled_pid : process_filters.included_process_ids()) {
+ *trace_event_data_source->add_producer_name_filter() = base::StrCat(
+ {mojom::kPerfettoProducerNamePrefix,
+ base::NumberToString(static_cast<uint32_t>(enabled_pid))});
+ }
+ }
+
+ // Capture system trace events if supported and enabled. The datasources will
+ // only emit events if system tracing is enabled in |chrome_config|.
+ if (!privacy_filtering_enabled) {
+#if defined(OS_CHROMEOS) || (BUILDFLAG(IS_CHROMECAST) && defined(OS_LINUX))
+ if (source_names.empty() ||
+ source_names.count(tracing::mojom::kSystemTraceDataSourceName) == 1) {
+ AddDataSourceConfig(perfetto_config,
+ tracing::mojom::kSystemTraceDataSourceName,
+ chrome_config_string, privacy_filtering_enabled);
+ }
+#endif
+
+#if defined(OS_CHROMEOS)
+ if (source_names.empty() ||
+ source_names.count(tracing::mojom::kArcTraceDataSourceName) == 1) {
+ AddDataSourceConfig(perfetto_config,
+ tracing::mojom::kArcTraceDataSourceName,
+ chrome_config_string, privacy_filtering_enabled);
+ }
+#endif
+ }
+
+ // Also capture global metadata.
+ if (source_names.empty() ||
+ source_names.count(tracing::mojom::kMetaDataSourceName) == 1) {
+ AddDataSourceConfig(perfetto_config, tracing::mojom::kMetaDataSourceName,
+ chrome_config_string, privacy_filtering_enabled);
+ }
+
+ if (stripped_config.IsCategoryGroupEnabled(
+ TRACE_DISABLED_BY_DEFAULT("cpu_profiler"))) {
+ DCHECK_EQ(
+ 1u, source_names.empty() ||
+ source_names.count(tracing::mojom::kSamplerProfilerSourceName));
+ AddDataSourceConfig(perfetto_config,
+ tracing::mojom::kSamplerProfilerSourceName,
+ chrome_config_string, privacy_filtering_enabled);
+ }
+
+ if (stripped_config.IsCategoryGroupEnabled(
+ TRACE_DISABLED_BY_DEFAULT("java-heap-profiler"))) {
+ DCHECK_EQ(1u, source_names.empty() ||
+ source_names.count(
+ tracing::mojom::kJavaHeapProfilerSourceName));
+ AddDataSourceConfig(perfetto_config,
+ tracing::mojom::kJavaHeapProfilerSourceName,
+ chrome_config_string, privacy_filtering_enabled);
+ }
+
+ if (source_names.empty() ||
+ source_names.count(tracing::mojom::kReachedCodeProfilerSourceName) == 1) {
+ AddDataSourceConfig(perfetto_config,
+ tracing::mojom::kReachedCodeProfilerSourceName,
+ chrome_config_string, privacy_filtering_enabled);
+ }
+}
+
} // namespace
perfetto::TraceConfig GetDefaultPerfettoConfig(
const base::trace_event::TraceConfig& chrome_config,
bool privacy_filtering_enabled) {
+ return GetPerfettoConfigWithDataSources(chrome_config, {},
+ privacy_filtering_enabled);
+}
+
+perfetto::TraceConfig COMPONENT_EXPORT(TRACING_CPP)
+ GetPerfettoConfigWithDataSources(
+ const base::trace_event::TraceConfig& chrome_config,
+ const std::set<std::string>& source_names,
+ bool privacy_filtering_enabled) {
perfetto::TraceConfig perfetto_config;
size_t size_limit = chrome_config.GetTraceBufferSizeInKb();
@@ -65,9 +153,18 @@ perfetto::TraceConfig GetDefaultPerfettoConfig(
break;
}
- // Perfetto uses clock_gettime for its internal snapshotting, which gets
- // blocked by the sandboxed and isn't needed for Chrome regardless.
auto* builtin_data_sources = perfetto_config.mutable_builtin_data_sources();
+
+ // Chrome uses CLOCK_MONOTONIC as its trace clock on Posix. To avoid that
+ // trace processor converts Chrome's event timestamps into CLOCK_BOOTTIME
+ // during import, we set the trace clock here (the service will emit it into
+ // the trace's ClockSnapshots). See also crbug.com/1060400, where the
+ // conversion to BOOTTIME caused CrOS and chromecast system data source data
+ // to be misaligned.
+ builtin_data_sources->set_primary_trace_clock(
+ static_cast<perfetto::protos::gen::BuiltinClock>(kTraceClockId));
+
+ // Chrome emits system / trace config metadata itself.
builtin_data_sources->set_disable_trace_config(privacy_filtering_enabled);
builtin_data_sources->set_disable_system_info(privacy_filtering_enabled);
builtin_data_sources->set_disable_service_events(privacy_filtering_enabled);
@@ -88,52 +185,10 @@ perfetto::TraceConfig GetDefaultPerfettoConfig(
base::trace_event::TraceConfig::ProcessFilterConfig());
stripped_config.SetTraceBufferSizeInKb(0);
stripped_config.SetTraceBufferSizeInEvents(0);
- std::string chrome_config_string = stripped_config.ToString();
-
- // Capture actual trace events.
- auto* trace_event_data_source = AddDataSourceConfig(
- &perfetto_config, tracing::mojom::kTraceEventDataSourceName,
- chrome_config_string, privacy_filtering_enabled);
- for (auto& enabled_pid :
- chrome_config.process_filter_config().included_process_ids()) {
- *trace_event_data_source->add_producer_name_filter() = base::StrCat(
- {mojom::kPerfettoProducerNamePrefix,
- base::NumberToString(static_cast<uint32_t>(enabled_pid))});
- }
-
-// Capture system trace events if supported and enabled. The datasources will
-// only emit events if system tracing is enabled in |chrome_config|.
- if (!privacy_filtering_enabled) {
-#if defined(OS_CHROMEOS) || (BUILDFLAG(IS_CHROMECAST) && defined(OS_LINUX))
- AddDataSourceConfig(&perfetto_config,
- tracing::mojom::kSystemTraceDataSourceName,
- chrome_config_string, privacy_filtering_enabled);
-#endif
-
-#if defined(OS_CHROMEOS)
- AddDataSourceConfig(&perfetto_config,
- tracing::mojom::kArcTraceDataSourceName,
- chrome_config_string, privacy_filtering_enabled);
-#endif
- }
- // Also capture global metadata.
- AddDataSourceConfig(&perfetto_config, tracing::mojom::kMetaDataSourceName,
- chrome_config_string, privacy_filtering_enabled);
-
- if (chrome_config.IsCategoryGroupEnabled(
- TRACE_DISABLED_BY_DEFAULT("cpu_profiler"))) {
- AddDataSourceConfig(&perfetto_config,
- tracing::mojom::kSamplerProfilerSourceName,
- chrome_config_string, privacy_filtering_enabled);
- }
-
- if (chrome_config.IsCategoryGroupEnabled(
- TRACE_DISABLED_BY_DEFAULT("java-heap-profiler"))) {
- AddDataSourceConfig(&perfetto_config,
- tracing::mojom::kJavaHeapProfilerSourceName,
- chrome_config_string, privacy_filtering_enabled);
- }
+ AddDataSourceConfigs(&perfetto_config, chrome_config.process_filter_config(),
+ stripped_config, source_names,
+ privacy_filtering_enabled);
return perfetto_config;
}
diff --git a/chromium/services/tracing/public/cpp/perfetto/perfetto_config.h b/chromium/services/tracing/public/cpp/perfetto/perfetto_config.h
index b4616787278..27d33a982c4 100644
--- a/chromium/services/tracing/public/cpp/perfetto/perfetto_config.h
+++ b/chromium/services/tracing/public/cpp/perfetto/perfetto_config.h
@@ -5,6 +5,9 @@
#ifndef SERVICES_TRACING_PUBLIC_CPP_PERFETTO_PERFETTO_CONFIG_H_
#define SERVICES_TRACING_PUBLIC_CPP_PERFETTO_PERFETTO_CONFIG_H_
+#include <set>
+#include <string>
+
#include "base/component_export.h"
#include "third_party/perfetto/include/perfetto/tracing/core/trace_config.h"
@@ -20,6 +23,16 @@ perfetto::TraceConfig COMPONENT_EXPORT(TRACING_CPP) GetDefaultPerfettoConfig(
const base::trace_event::TraceConfig& chrome_config,
bool privacy_filtering_enabled = false);
+// Creates a perfetto trace config with only the data sources included in
+// |source_names| and enabled by |trace_config|. Passing empty set will add all
+// data sources based on trace config. The list of possible names are listed in
+// services/tracing/public/mojom/perfetto_service.mojom.
+perfetto::TraceConfig COMPONENT_EXPORT(TRACING_CPP)
+ GetPerfettoConfigWithDataSources(
+ const base::trace_event::TraceConfig& chrome_config,
+ const std::set<std::string>& source_names,
+ bool privacy_filtering_enabled = false);
+
} // namespace tracing
#endif // SERVICES_TRACING_PUBLIC_CPP_PERFETTO_PERFETTO_CONFIG_H_
diff --git a/chromium/services/tracing/public/cpp/perfetto/posix_system_producer.cc b/chromium/services/tracing/public/cpp/perfetto/posix_system_producer.cc
index a782ff7748b..0f144724150 100644
--- a/chromium/services/tracing/public/cpp/perfetto/posix_system_producer.cc
+++ b/chromium/services/tracing/public/cpp/perfetto/posix_system_producer.cc
@@ -14,6 +14,7 @@
#include "services/tracing/public/cpp/perfetto/shared_memory.h"
#include "services/tracing/public/cpp/trace_startup.h"
#include "services/tracing/public/cpp/traced_process_impl.h"
+#include "services/tracing/public/cpp/tracing_features.h"
#include "third_party/perfetto/include/perfetto/ext/tracing/core/commit_data_request.h"
#include "third_party/perfetto/include/perfetto/ext/tracing/core/shared_memory_arbiter.h"
#include "third_party/perfetto/include/perfetto/ext/tracing/core/trace_writer.h"
@@ -135,6 +136,13 @@ void PosixSystemProducer::ConnectToSystemService() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
CHECK(IsTracingInitialized());
DCHECK(state_ == State::kDisconnected);
+
+ // Some Telemetry tests use sideloaded Perfetto library on pre-Pie devices.
+ // We allow those tests to use system tracing by setting the
+ // EnablePerfettoSystemTracing feature.
+ disallow_pre_android_pie_ =
+ !base::FeatureList::IsEnabled(features::kEnablePerfettoSystemTracing);
+
Connect();
}
diff --git a/chromium/services/tracing/public/cpp/perfetto/producer_client.cc b/chromium/services/tracing/public/cpp/perfetto/producer_client.cc
index f8f3a133b42..edbda2af892 100644
--- a/chromium/services/tracing/public/cpp/perfetto/producer_client.cc
+++ b/chromium/services/tracing/public/cpp/perfetto/producer_client.cc
@@ -25,30 +25,7 @@
#include "third_party/perfetto/include/perfetto/protozero/scattered_stream_writer.h"
#include "third_party/perfetto/protos/perfetto/common/track_event_descriptor.pbzero.h"
-#if defined(OS_LINUX)
-#include "components/crash/core/app/crashpad.h" // nogncheck
-#endif
-
namespace {
-#if defined(OS_LINUX)
-constexpr char kCrashHandlerMetricName[] =
- "CrashReport.DumpWithoutCrashingHandler.FromInitSharedMemoryIfNeeded";
-// Crash handler that might handle base::debug::DumpWithoutCrashing.
-// TODO(crbug.com/1074115): Remove once crbug.com/1074115 is resolved.
-// These values are persisted to logs. Entries should not be renumbered and
-// numeric values should never be reused.
-enum class CrashHandler {
- kCrashpad = 0,
- kBreakpad = 1,
- kMaxValue = kBreakpad,
-};
-#endif
-
-// UMA that records the return value of base::debug::DumpWithoutCrashing.
-// TODO(crbug.com/1074115): Remove once crbug.com/1074115 is resolved.
-constexpr char kDumpWithoutCrashingResultMetricName[] =
- "CrashReport.DumpWithoutCrashingResult.FromInitSharedMemoryIfNeeded";
-
// Result for getting the shared buffer in InitSharedMemoryIfNeeded.
constexpr char kSharedBufferIsValidMetricName[] = "Tracing.SharedBufferIsValid";
} // namespace
@@ -421,18 +398,17 @@ bool ProducerClient::InitSharedMemoryIfNeeded() {
base::UmaHistogramBoolean(kSharedBufferIsValidMetricName, valid);
if (!valid) {
-#if defined(OS_LINUX)
// TODO(crbug.com/1074115): Investigate why Breakpad doesn't seem to
// generate reports on some ChromeOS boards.
- CrashHandler handler = crash_reporter::IsCrashpadEnabled()
- ? CrashHandler::kCrashpad
- : CrashHandler::kBreakpad;
- base::UmaHistogramEnumeration(kCrashHandlerMetricName, handler);
-#endif
+ if (pre_dump_error_callback_) {
+ pre_dump_error_callback_.Run();
+ }
bool dump_with_crashing_result = base::debug::DumpWithoutCrashing();
- base::UmaHistogramBoolean(kDumpWithoutCrashingResultMetricName,
- dump_with_crashing_result);
+
+ if (post_dump_error_callback_) {
+ post_dump_error_callback_.Run(dump_with_crashing_result);
+ }
LOG(ERROR) << "Failed to create tracing SMB";
shared_memory_.reset();
@@ -493,4 +469,12 @@ void ProducerClient::NotifyDataSourceFlushComplete(
}
}
+void ProducerClient::SetBufferAllocationFailureCallbacks(
+ base::Closure pre_dump_error_callback,
+ base::Callback<void(bool dump_result)> post_dump_error_callback) {
+ base::AutoLock lock(lock_);
+ pre_dump_error_callback_ = std::move(pre_dump_error_callback);
+ post_dump_error_callback_ = std::move(post_dump_error_callback);
+}
+
} // namespace tracing
diff --git a/chromium/services/tracing/public/cpp/perfetto/producer_client.h b/chromium/services/tracing/public/cpp/perfetto/producer_client.h
index d831ca81145..63a010f43ac 100644
--- a/chromium/services/tracing/public/cpp/perfetto/producer_client.h
+++ b/chromium/services/tracing/public/cpp/perfetto/producer_client.h
@@ -12,6 +12,7 @@
#include <vector>
#include "base/atomicops.h"
+#include "base/callback_forward.h"
#include "base/component_export.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
@@ -108,6 +109,13 @@ class COMPONENT_EXPORT(TRACING_CPP) ProducerClient
mojo::PendingRemote<mojom::ProducerHost>);
perfetto::SharedMemory* shared_memory_for_testing();
+ // Callbacks that are triggered if this class cannot allocate its shared
+ // buffer. For error reporting. The second callback is called after
+ // DumpWithoutCrashing is called, and includes the result of that call.
+ void SetBufferAllocationFailureCallbacks(
+ base::Closure pre_dump_error_callback,
+ base::Callback<void(bool dump_result)> post_dump_error_callback);
+
protected:
// Protected for testing. Returns false if SMB creation failed.
bool InitSharedMemoryIfNeeded();
@@ -142,6 +150,12 @@ class COMPONENT_EXPORT(TRACING_CPP) ProducerClient
std::unique_ptr<perfetto::SharedMemoryArbiter> shared_memory_arbiter_
GUARDED_BY(lock_);
+ // See ProducerClient::SetBufferAllocationFailureCallbacks for details of
+ // what these callbacks mean.
+ base::Closure pre_dump_error_callback_ GUARDED_BY(lock_);
+ base::Callback<void(bool dump_without_crashing_result)>
+ post_dump_error_callback_ GUARDED_BY(lock_);
+
// NOTE: Weak pointers must be invalidated before all other member variables.
base::WeakPtrFactory<ProducerClient> weak_ptr_factory_{this};
DISALLOW_COPY_AND_ASSIGN(ProducerClient);
diff --git a/chromium/services/tracing/public/cpp/perfetto/producer_test_utils.cc b/chromium/services/tracing/public/cpp/perfetto/producer_test_utils.cc
new file mode 100644
index 00000000000..7ec9798e28a
--- /dev/null
+++ b/chromium/services/tracing/public/cpp/perfetto/producer_test_utils.cc
@@ -0,0 +1,161 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "services/tracing/public/cpp/perfetto/producer_test_utils.h"
+
+#include <deque>
+#include <functional>
+#include <utility>
+
+#include "base/debug/leak_annotations.h"
+#include "base/optional.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/perfetto/include/perfetto/ext/base/utils.h"
+#include "third_party/perfetto/include/perfetto/ext/tracing/core/trace_writer.h"
+
+namespace tracing {
+
+namespace {
+
+// For sequences/threads other than our own, we just want to ignore
+// any events coming in.
+class DummyTraceWriter : public perfetto::TraceWriter {
+ public:
+ DummyTraceWriter()
+ : delegate_(perfetto::base::kPageSize), stream_(&delegate_) {}
+
+ perfetto::TraceWriter::TracePacketHandle NewTracePacket() override {
+ stream_.Reset(delegate_.GetNewBuffer());
+ trace_packet_.Reset(&stream_);
+
+ return perfetto::TraceWriter::TracePacketHandle(&trace_packet_);
+ }
+
+ void Flush(std::function<void()> callback = {}) override {}
+
+ perfetto::WriterID writer_id() const override {
+ return perfetto::WriterID(0);
+ }
+
+ uint64_t written() const override { return 0u; }
+
+ private:
+ perfetto::protos::pbzero::TracePacket trace_packet_;
+ protozero::ScatteredStreamWriterNullDelegate delegate_;
+ protozero::ScatteredStreamWriter stream_;
+};
+
+} // namespace
+
+TestProducerClient::TestProducerClient(
+ std::unique_ptr<PerfettoTaskRunner> main_thread_task_runner,
+ bool log_only_main_thread)
+ : ProducerClient(main_thread_task_runner.get()),
+ delegate_(perfetto::base::kPageSize),
+ stream_(&delegate_),
+ main_thread_task_runner_(std::move(main_thread_task_runner)),
+ log_only_main_thread_(log_only_main_thread) {
+ trace_packet_.Reset(&stream_);
+}
+
+TestProducerClient::~TestProducerClient() = default;
+
+std::unique_ptr<perfetto::TraceWriter> TestProducerClient::CreateTraceWriter(
+ perfetto::BufferID target_buffer,
+ perfetto::BufferExhaustedPolicy) {
+ // We attempt to destroy TraceWriters on thread shutdown in
+ // ThreadLocalStorage::Slot, by posting them to the ProducerClient taskrunner,
+ // but there's no guarantee that this will succeed if that taskrunner is also
+ // shut down.
+ ANNOTATE_SCOPED_MEMORY_LEAK;
+ if (!log_only_main_thread_ ||
+ main_thread_task_runner_->GetOrCreateTaskRunner()
+ ->RunsTasksInCurrentSequence()) {
+ return std::make_unique<TestTraceWriter>(this);
+ } else {
+ return std::make_unique<DummyTraceWriter>();
+ }
+}
+
+void TestProducerClient::FlushPacketIfPossible() {
+ // GetNewBuffer() in ScatteredStreamWriterNullDelegate doesn't
+ // actually return a new buffer, but rather lets us access the buffer
+ // buffer already used by protozero to write the TracePacket into.
+ protozero::ContiguousMemoryRange buffer = delegate_.GetNewBuffer();
+
+ uint32_t message_size = trace_packet_.Finalize();
+ if (message_size) {
+ EXPECT_GE(buffer.size(), message_size);
+
+ auto proto = std::make_unique<perfetto::protos::TracePacket>();
+ EXPECT_TRUE(proto->ParseFromArray(buffer.begin, message_size));
+ if (proto->has_chrome_events() &&
+ proto->chrome_events().metadata().size() > 0) {
+ legacy_metadata_packets_.push_back(std::move(proto));
+ } else if (proto->has_chrome_metadata()) {
+ proto_metadata_packets_.push_back(std::move(proto));
+ } else {
+ finalized_packets_.push_back(std::move(proto));
+ }
+ }
+
+ stream_.Reset(buffer);
+ trace_packet_.Reset(&stream_);
+}
+
+perfetto::protos::pbzero::TracePacket* TestProducerClient::NewTracePacket() {
+ FlushPacketIfPossible();
+
+ return &trace_packet_;
+}
+
+size_t TestProducerClient::GetFinalizedPacketCount() {
+ FlushPacketIfPossible();
+ return finalized_packets_.size();
+}
+
+const perfetto::protos::TracePacket* TestProducerClient::GetFinalizedPacket(
+ size_t packet_index) {
+ FlushPacketIfPossible();
+ EXPECT_GT(finalized_packets_.size(), packet_index);
+ return finalized_packets_[packet_index].get();
+}
+
+const google::protobuf::RepeatedPtrField<perfetto::protos::ChromeMetadata>*
+TestProducerClient::GetChromeMetadata(size_t packet_index) {
+ FlushPacketIfPossible();
+ if (legacy_metadata_packets_.empty()) {
+ return nullptr;
+ }
+ EXPECT_GT(legacy_metadata_packets_.size(), packet_index);
+
+ const auto& event_bundle =
+ legacy_metadata_packets_[packet_index]->chrome_events();
+ return &event_bundle.metadata();
+}
+
+const perfetto::protos::ChromeMetadataPacket*
+TestProducerClient::GetProtoChromeMetadata(size_t packet_index) {
+ FlushPacketIfPossible();
+ EXPECT_GT(proto_metadata_packets_.size(), packet_index);
+ return &proto_metadata_packets_[packet_index]->chrome_metadata();
+}
+
+TestTraceWriter::TestTraceWriter(TestProducerClient* producer_client)
+ : producer_client_(producer_client) {}
+
+perfetto::TraceWriter::TracePacketHandle TestTraceWriter::NewTracePacket() {
+ return perfetto::TraceWriter::TracePacketHandle(
+ producer_client_->NewTracePacket());
+}
+
+perfetto::WriterID TestTraceWriter::writer_id() const {
+ return perfetto::WriterID(0);
+}
+
+uint64_t TestTraceWriter::written() const {
+ return 0u;
+}
+
+} // namespace tracing
diff --git a/chromium/services/tracing/public/cpp/perfetto/producer_test_utils.h b/chromium/services/tracing/public/cpp/perfetto/producer_test_utils.h
new file mode 100644
index 00000000000..bbab71f84da
--- /dev/null
+++ b/chromium/services/tracing/public/cpp/perfetto/producer_test_utils.h
@@ -0,0 +1,94 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef SERVICES_TRACING_PUBLIC_CPP_PERFETTO_PRODUCER_TEST_UTILS_H_
+#define SERVICES_TRACING_PUBLIC_CPP_PERFETTO_PRODUCER_TEST_UTILS_H_
+
+#include <memory>
+#include <vector>
+
+#include "base/callback_forward.h"
+#include "base/optional.h"
+#include "services/tracing/public/cpp/perfetto/producer_client.h"
+#include "services/tracing/public/cpp/perfetto/task_runner.h"
+#include "third_party/perfetto/include/perfetto/ext/tracing/core/trace_writer.h"
+#include "third_party/perfetto/include/perfetto/protozero/scattered_stream_null_delegate.h"
+#include "third_party/perfetto/protos/perfetto/trace/chrome/chrome_trace_event.pb.h"
+#include "third_party/perfetto/protos/perfetto/trace/trace_packet.pb.h"
+#include "third_party/perfetto/protos/perfetto/trace/trace_packet.pbzero.h"
+
+namespace tracing {
+
+// Test producer client for data source tests.
+class TestProducerClient : public ProducerClient {
+ public:
+ explicit TestProducerClient(
+ std::unique_ptr<PerfettoTaskRunner> main_thread_task_runner,
+ bool log_only_main_thread = true);
+ ~TestProducerClient() override;
+
+ // ProducerClient implementation:
+ std::unique_ptr<perfetto::TraceWriter> CreateTraceWriter(
+ perfetto::BufferID target_buffer,
+ perfetto::BufferExhaustedPolicy =
+ perfetto::BufferExhaustedPolicy::kDefault) override;
+
+ void FlushPacketIfPossible();
+
+ perfetto::protos::pbzero::TracePacket* NewTracePacket();
+
+ size_t GetFinalizedPacketCount();
+
+ const perfetto::protos::TracePacket* GetFinalizedPacket(
+ size_t packet_index = 0);
+
+ const google::protobuf::RepeatedPtrField<perfetto::protos::ChromeMetadata>*
+ GetChromeMetadata(size_t packet_index = 0);
+
+ const perfetto::protos::ChromeMetadataPacket* GetProtoChromeMetadata(
+ size_t packet_index = 0);
+
+ const std::vector<std::unique_ptr<perfetto::protos::TracePacket>>&
+ finalized_packets() const {
+ return finalized_packets_;
+ }
+
+ TestProducerClient(TestProducerClient&&) = delete;
+ TestProducerClient& operator=(TestProducerClient&&) = delete;
+
+ private:
+ std::vector<std::unique_ptr<perfetto::protos::TracePacket>>
+ finalized_packets_;
+ std::vector<std::unique_ptr<perfetto::protos::TracePacket>>
+ legacy_metadata_packets_;
+ std::vector<std::unique_ptr<perfetto::protos::TracePacket>>
+ proto_metadata_packets_;
+ perfetto::protos::pbzero::TracePacket trace_packet_;
+ protozero::ScatteredStreamWriterNullDelegate delegate_;
+ protozero::ScatteredStreamWriter stream_;
+ std::unique_ptr<PerfettoTaskRunner> main_thread_task_runner_;
+ bool log_only_main_thread_;
+};
+
+class TestTraceWriter : public perfetto::TraceWriter {
+ public:
+ using TracePacketCallback = base::RepeatingCallback<void(
+ std::unique_ptr<perfetto::protos::TracePacket>)>;
+ explicit TestTraceWriter(TestProducerClient* producer_client);
+
+ perfetto::TraceWriter::TracePacketHandle NewTracePacket() override;
+ void Flush(std::function<void()> callback = {}) override {}
+ perfetto::WriterID writer_id() const override;
+ uint64_t written() const override;
+
+ TestTraceWriter(TestTraceWriter&&) = delete;
+ TestTraceWriter& operator=(TestTraceWriter&&) = delete;
+
+ private:
+ TestProducerClient* producer_client_;
+};
+
+} // namespace tracing
+
+#endif // SERVICES_TRACING_PUBLIC_CPP_PERFETTO_PRODUCER_TEST_UTILS_H_
diff --git a/chromium/services/tracing/public/cpp/perfetto/system_trace_writer.h b/chromium/services/tracing/public/cpp/perfetto/system_trace_writer.h
index cdc96cffe61..c2f421e4b61 100644
--- a/chromium/services/tracing/public/cpp/perfetto/system_trace_writer.h
+++ b/chromium/services/tracing/public/cpp/perfetto/system_trace_writer.h
@@ -8,8 +8,8 @@
#include <list>
#include "base/bind.h"
+#include "base/check.h"
#include "base/component_export.h"
-#include "base/logging.h"
#include "base/macros.h"
#include "base/memory/ref_counted_memory.h"
#include "base/memory/weak_ptr.h"
diff --git a/chromium/services/tracing/public/cpp/perfetto/trace_event_data_source.cc b/chromium/services/tracing/public/cpp/perfetto/trace_event_data_source.cc
index 6b7435c631e..88506ec5207 100644
--- a/chromium/services/tracing/public/cpp/perfetto/trace_event_data_source.cc
+++ b/chromium/services/tracing/public/cpp/perfetto/trace_event_data_source.cc
@@ -39,10 +39,11 @@
#include "services/tracing/public/cpp/perfetto/macros.h"
#include "services/tracing/public/cpp/perfetto/perfetto_producer.h"
#include "services/tracing/public/cpp/perfetto/perfetto_traced_process.h"
+#include "services/tracing/public/cpp/perfetto/system_producer.h"
#include "services/tracing/public/cpp/perfetto/trace_time.h"
#include "services/tracing/public/cpp/perfetto/traced_value_proto_writer.h"
#include "services/tracing/public/cpp/perfetto/track_event_thread_local_event_sink.h"
-#include "services/tracing/public/cpp/trace_event_args_whitelist.h"
+#include "services/tracing/public/cpp/trace_event_args_allowlist.h"
#include "services/tracing/public/cpp/trace_startup.h"
#include "services/tracing/public/mojom/constants.mojom.h"
#include "third_party/perfetto/include/perfetto/ext/tracing/core/shared_memory_arbiter.h"
@@ -176,11 +177,11 @@ TraceEventMetadataSource::GenerateTraceConfigMetadataDict() {
auto metadata_dict = std::make_unique<base::DictionaryValue>();
// If argument filtering is enabled, we need to check if the trace config is
- // whitelisted before emitting it.
+ // allowlisted before emitting it.
// TODO(eseckler): Figure out a way to solve this without calling directly
- // into IsMetadataWhitelisted().
+ // into IsMetadataAllowlisted().
if (!parsed_chrome_config_->IsArgumentFilterEnabled() ||
- IsMetadataWhitelisted("trace-config")) {
+ IsMetadataAllowlisted("trace-config")) {
metadata_dict->SetString("trace-config", chrome_config_);
} else {
metadata_dict->SetString("trace-config", "__stripped__");
@@ -458,11 +459,13 @@ TraceEventDataSource::~TraceEventDataSource() = default;
void TraceEventDataSource::RegisterStartupHooks() {
RegisterTracedValueProtoWriter();
+ base::trace_event::EnableTypedTraceEvents(
+ &TraceEventDataSource::OnAddTypedTraceEvent);
}
void TraceEventDataSource::RegisterWithTraceLog() {
TraceLog::GetInstance()->SetAddTraceEventOverrides(
- &TraceEventDataSource::OnAddTraceEvent,
+ &TraceEventDataSource::OnAddLegacyTraceEvent,
&TraceEventDataSource::FlushCurrentThread,
&TraceEventDataSource::OnUpdateDuration);
base::AutoLock l(lock_);
@@ -498,8 +501,7 @@ void TraceEventDataSource::OnStopTracingDone() {
}
// static
-TrackEventThreadLocalEventSink* TraceEventDataSource::GetOrPrepareEventSink(
- bool thread_will_flush) {
+TrackEventThreadLocalEventSink* TraceEventDataSource::GetOrPrepareEventSink() {
// Avoid re-entrancy, which can happen during PostTasks (the taskqueue can
// emit trace events). We discard the events in this case, as any PostTasking
// to deal with these events later would break the event ordering that the
@@ -536,8 +538,7 @@ TrackEventThreadLocalEventSink* TraceEventDataSource::GetOrPrepareEventSink(
}
if (!thread_local_event_sink) {
- thread_local_event_sink =
- GetInstance()->CreateThreadLocalEventSink(thread_will_flush);
+ thread_local_event_sink = GetInstance()->CreateThreadLocalEventSink();
ThreadLocalEventSinkSlot()->Set(thread_local_event_sink);
}
@@ -869,7 +870,7 @@ void TraceEventDataSource::LogHistogram(base::HistogramBase* histogram) {
base::Base64Encode(
std::string(static_cast<const char*>(pickle.data()), pickle.size()),
&buckets);
- TRACE_EVENT_INSTANT2("benchmark", "UMAHistogramSamples",
+ TRACE_EVENT_INSTANT2("benchmark,uma", "UMAHistogramSamples",
TRACE_EVENT_SCOPE_PROCESS, "name",
histogram->histogram_name(), "buckets", buckets);
}
@@ -929,7 +930,7 @@ TraceEventDataSource::CreateTraceWriterLocked() {
}
TrackEventThreadLocalEventSink*
-TraceEventDataSource::CreateThreadLocalEventSink(bool thread_will_flush) {
+TraceEventDataSource::CreateThreadLocalEventSink() {
AutoLockWithDeferredTaskPosting lock(lock_);
uint32_t session_id =
session_flags_.load(std::memory_order_relaxed).session_id;
@@ -945,12 +946,27 @@ TraceEventDataSource::CreateThreadLocalEventSink(bool thread_will_flush) {
}
// static
-void TraceEventDataSource::OnAddTraceEvent(
+void TraceEventDataSource::OnAddLegacyTraceEvent(
TraceEvent* trace_event,
bool thread_will_flush,
base::trace_event::TraceEventHandle* handle) {
- OnAddTraceEvent(trace_event, thread_will_flush, handle, perfetto::Track(),
- [](perfetto::EventContext) {});
+ auto* thread_local_event_sink = GetOrPrepareEventSink();
+ if (thread_local_event_sink) {
+ AutoThreadLocalBoolean thread_is_in_trace_event(
+ GetThreadIsInTraceEventTLS());
+ thread_local_event_sink->AddLegacyTraceEvent(trace_event, handle);
+ }
+}
+
+// static
+base::trace_event::TrackEventHandle TraceEventDataSource::OnAddTypedTraceEvent(
+ base::trace_event::TraceEvent* trace_event) {
+ auto* thread_local_event_sink = GetOrPrepareEventSink();
+ if (thread_local_event_sink) {
+ // GetThreadIsInTraceEventTLS() is handled by the sink for typed events.
+ return thread_local_event_sink->AddTypedTraceEvent(trace_event);
+ }
+ return base::trace_event::TrackEventHandle();
}
// static
@@ -1109,6 +1125,23 @@ void TraceEventDataSource::EmitTrackDescriptor() {
chrome_process->set_process_type(process_type);
}
+#if defined(OS_ANDROID)
+ // Host app package name is only recorded if privacy filtering is disabled or
+ // this is a system trace.
+ if (!privacy_filtering_enabled_ ||
+ producer_ == PerfettoTracedProcess::Get()->system_producer()) {
+ // Host app package name is used to group information from different
+ // processes that "belong" to the same WebView app.
+ // TODO(b/161983088): only write this for WebView since this information is
+ // not useful in other cases.
+ if (process_type == ChromeProcessDescriptor::PROCESS_RENDERER ||
+ process_type == ChromeProcessDescriptor::PROCESS_BROWSER) {
+ chrome_process->set_host_app_package_name(
+ base::android::BuildInfo::GetInstance()->host_package_name());
+ }
+ }
+#endif // defined(OS_ANDROID)
+
// TODO(eseckler): Set other fields on |chrome_process|.
trace_packet = TracePacketHandle();
diff --git a/chromium/services/tracing/public/cpp/perfetto/trace_event_data_source.h b/chromium/services/tracing/public/cpp/perfetto/trace_event_data_source.h
index ce909395611..ad6943fb834 100644
--- a/chromium/services/tracing/public/cpp/perfetto/trace_event_data_source.h
+++ b/chromium/services/tracing/public/cpp/perfetto/trace_event_data_source.h
@@ -20,6 +20,7 @@
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "base/trace_event/trace_config.h"
+#include "base/trace_event/typed_macros.h"
#include "services/tracing/public/cpp/perfetto/perfetto_traced_process.h"
#include "services/tracing/public/cpp/perfetto/track_event_thread_local_event_sink.h"
#include "third_party/perfetto/protos/perfetto/trace/chrome/chrome_metadata.pbzero.h"
@@ -35,7 +36,6 @@ struct TraceEventHandle;
namespace perfetto {
class TraceWriter;
-class EventContext;
}
namespace tracing {
@@ -180,24 +180,6 @@ class COMPONENT_EXPORT(TRACING_CPP) TraceEventDataSource
bool IsEnabled();
- static TrackEventThreadLocalEventSink* GetOrPrepareEventSink(
- bool thread_will_flush);
-
- template <
- typename TrackEventArgumentFunction = void (*)(perfetto::EventContext)>
- static void OnAddTraceEvent(base::trace_event::TraceEvent* trace_event,
- bool thread_will_flush,
- base::trace_event::TraceEventHandle* handle,
- const perfetto::Track& track,
- TrackEventArgumentFunction func) {
- auto* thread_local_event_sink = GetOrPrepareEventSink(thread_will_flush);
- if (thread_local_event_sink) {
- AutoThreadLocalBoolean thread_is_in_trace_event(
- GetThreadIsInTraceEventTLS());
- thread_local_event_sink->AddTraceEvent(trace_event, handle, track, func);
- }
- }
-
// Registered with base::StatisticsRecorder to receive a callback on every
// histogram sample which gets added.
static void OnMetricsSampleCallback(const char* histogram_name,
@@ -226,13 +208,17 @@ class COMPONENT_EXPORT(TRACING_CPP) TraceEventDataSource
void OnStopTracingDone();
std::unique_ptr<perfetto::TraceWriter> CreateTraceWriterLocked();
- TrackEventThreadLocalEventSink* CreateThreadLocalEventSink(
- bool thread_will_flush);
+ TrackEventThreadLocalEventSink* CreateThreadLocalEventSink();
+
+ static TrackEventThreadLocalEventSink* GetOrPrepareEventSink();
- // Callback from TraceLog, can be called from any thread.
- static void OnAddTraceEvent(base::trace_event::TraceEvent* trace_event,
- bool thread_will_flush,
- base::trace_event::TraceEventHandle* handle);
+ // Callback from TraceLog / typed macros, can be called from any thread.
+ static void OnAddLegacyTraceEvent(
+ base::trace_event::TraceEvent* trace_event,
+ bool thread_will_flush,
+ base::trace_event::TraceEventHandle* handle);
+ static base::trace_event::TrackEventHandle OnAddTypedTraceEvent(
+ base::trace_event::TraceEvent* trace_event);
static void OnUpdateDuration(
const unsigned char* category_group_enabled,
const char* name,
diff --git a/chromium/services/tracing/public/cpp/perfetto/trace_event_data_source_unittest.cc b/chromium/services/tracing/public/cpp/perfetto/trace_event_data_source_unittest.cc
index 17067c8761d..83af5e52128 100644
--- a/chromium/services/tracing/public/cpp/perfetto/trace_event_data_source_unittest.cc
+++ b/chromium/services/tracing/public/cpp/perfetto/trace_event_data_source_unittest.cc
@@ -6,13 +6,13 @@
#include <map>
#include <memory>
+#include <set>
#include <utility>
#include <vector>
#include "base/bind.h"
#include "base/callback.h"
#include "base/command_line.h"
-#include "base/debug/leak_annotations.h"
#include "base/json/json_reader.h"
#include "base/metrics/histogram_macros.h"
#include "base/metrics/metrics_hashes.h"
@@ -31,14 +31,10 @@
#include "base/trace_event/trace_log.h"
#include "components/tracing/common/tracing_switches.h"
#include "services/tracing/public/cpp/perfetto/macros.h"
-#include "services/tracing/public/cpp/perfetto/producer_client.h"
+#include "services/tracing/public/cpp/perfetto/producer_test_utils.h"
#include "services/tracing/public/cpp/perfetto/trace_time.h"
#include "services/tracing/public/mojom/perfetto_service.mojom.h"
#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/perfetto/include/perfetto/ext/base/utils.h"
-#include "third_party/perfetto/include/perfetto/ext/tracing/core/trace_writer.h"
-#include "third_party/perfetto/include/perfetto/protozero/scattered_stream_null_delegate.h"
-#include "third_party/perfetto/include/perfetto/protozero/scattered_stream_writer.h"
#include "third_party/perfetto/include/perfetto/tracing/track.h"
#include "third_party/perfetto/protos/perfetto/trace/clock_snapshot.pb.h"
#include "third_party/perfetto/protos/perfetto/trace/trace_packet.pb.h"
@@ -64,173 +60,10 @@ constexpr const char kCategoryGroup[] = "foo";
constexpr uint32_t kClockIdAbsolute = 64;
constexpr uint32_t kClockIdIncremental = 65;
-class MockProducerClient : public ProducerClient {
- public:
- explicit MockProducerClient(
- std::unique_ptr<PerfettoTaskRunner> main_thread_task_runner)
- : ProducerClient(main_thread_task_runner.get()),
- delegate_(perfetto::base::kPageSize),
- stream_(&delegate_),
- main_thread_task_runner_(std::move(main_thread_task_runner)) {
- trace_packet_.Reset(&stream_);
- }
-
- std::unique_ptr<perfetto::TraceWriter> CreateTraceWriter(
- perfetto::BufferID target_buffer,
- perfetto::BufferExhaustedPolicy =
- perfetto::BufferExhaustedPolicy::kDefault) override;
-
- void FlushPacketIfPossible() {
- // GetNewBuffer() in ScatteredStreamWriterNullDelegate doesn't
- // actually return a new buffer, but rather lets us access the buffer
- // buffer already used by protozero to write the TracePacket into.
- protozero::ContiguousMemoryRange buffer = delegate_.GetNewBuffer();
-
- uint32_t message_size = trace_packet_.Finalize();
- if (message_size) {
- EXPECT_GE(buffer.size(), message_size);
-
- auto proto = std::make_unique<perfetto::protos::TracePacket>();
- EXPECT_TRUE(proto->ParseFromArray(buffer.begin, message_size));
- if (proto->has_chrome_events() &&
- proto->chrome_events().metadata().size() > 0) {
- legacy_metadata_packets_.push_back(std::move(proto));
- } else if (proto->has_chrome_metadata()) {
- proto_metadata_packets_.push_back(std::move(proto));
- } else {
- finalized_packets_.push_back(std::move(proto));
- }
- }
-
- stream_.Reset(buffer);
- trace_packet_.Reset(&stream_);
- }
-
- perfetto::protos::pbzero::TracePacket* NewTracePacket() {
- FlushPacketIfPossible();
-
- return &trace_packet_;
- }
-
- size_t GetFinalizedPacketCount() {
- FlushPacketIfPossible();
- return finalized_packets_.size();
- }
-
- const perfetto::protos::TracePacket* GetFinalizedPacket(
- size_t packet_index = 0) {
- FlushPacketIfPossible();
- EXPECT_GT(finalized_packets_.size(), packet_index);
- return finalized_packets_[packet_index].get();
- }
-
- const google::protobuf::RepeatedPtrField<perfetto::protos::ChromeMetadata>
- GetChromeMetadata(size_t packet_index = 0) {
- FlushPacketIfPossible();
- if (legacy_metadata_packets_.empty()) {
- return google::protobuf::RepeatedPtrField<
- perfetto::protos::ChromeMetadata>();
- }
- EXPECT_GT(legacy_metadata_packets_.size(), packet_index);
-
- auto event_bundle = legacy_metadata_packets_[packet_index]->chrome_events();
- return event_bundle.metadata();
- }
-
- const perfetto::protos::ChromeMetadataPacket* GetProtoChromeMetadata(
- size_t packet_index = 0) {
- FlushPacketIfPossible();
- EXPECT_GT(proto_metadata_packets_.size(), packet_index);
- return &proto_metadata_packets_[packet_index]->chrome_metadata();
- }
-
- const std::vector<std::unique_ptr<perfetto::protos::TracePacket>>&
- finalized_packets() {
- return finalized_packets_;
- }
-
- private:
- std::vector<std::unique_ptr<perfetto::protos::TracePacket>>
- finalized_packets_;
- std::vector<std::unique_ptr<perfetto::protos::TracePacket>>
- legacy_metadata_packets_;
- std::vector<std::unique_ptr<perfetto::protos::TracePacket>>
- proto_metadata_packets_;
- perfetto::protos::pbzero::TracePacket trace_packet_;
- protozero::ScatteredStreamWriterNullDelegate delegate_;
- protozero::ScatteredStreamWriter stream_;
- std::unique_ptr<PerfettoTaskRunner> main_thread_task_runner_;
-};
-
-// For sequences/threads other than our own, we just want to ignore
-// any events coming in.
-class DummyTraceWriter : public perfetto::TraceWriter {
- public:
- DummyTraceWriter()
- : delegate_(perfetto::base::kPageSize), stream_(&delegate_) {}
-
- perfetto::TraceWriter::TracePacketHandle NewTracePacket() override {
- stream_.Reset(delegate_.GetNewBuffer());
- trace_packet_.Reset(&stream_);
-
- return perfetto::TraceWriter::TracePacketHandle(&trace_packet_);
- }
-
- void Flush(std::function<void()> callback = {}) override {}
-
- perfetto::WriterID writer_id() const override {
- return perfetto::WriterID(0);
- }
-
- uint64_t written() const override { return 0u; }
-
- private:
- perfetto::protos::pbzero::TracePacket trace_packet_;
- protozero::ScatteredStreamWriterNullDelegate delegate_;
- protozero::ScatteredStreamWriter stream_;
-};
-
-class MockTraceWriter : public perfetto::TraceWriter {
- public:
- explicit MockTraceWriter(MockProducerClient* producer_client)
- : producer_client_(producer_client) {}
-
- perfetto::TraceWriter::TracePacketHandle NewTracePacket() override {
- return perfetto::TraceWriter::TracePacketHandle(
- producer_client_->NewTracePacket());
- }
-
- void Flush(std::function<void()> callback = {}) override {}
-
- perfetto::WriterID writer_id() const override {
- return perfetto::WriterID(0);
- }
-
- uint64_t written() const override { return 0u; }
-
- private:
- MockProducerClient* producer_client_;
-};
-
-std::unique_ptr<perfetto::TraceWriter> MockProducerClient::CreateTraceWriter(
- perfetto::BufferID target_buffer,
- perfetto::BufferExhaustedPolicy) {
- // We attempt to destroy TraceWriters on thread shutdown in
- // ThreadLocalStorage::Slot, by posting them to the ProducerClient taskrunner,
- // but there's no guarantee that this will succeed if that taskrunner is also
- // shut down.
- ANNOTATE_SCOPED_MEMORY_LEAK;
- if (main_thread_task_runner_->GetOrCreateTaskRunner()
- ->RunsTasksInCurrentSequence()) {
- return std::make_unique<MockTraceWriter>(this);
- } else {
- return std::make_unique<DummyTraceWriter>();
- }
-}
-
class TraceEventDataSourceTest : public testing::Test {
public:
void SetUp() override {
+ TraceEventDataSource::GetInstance()->RegisterStartupHooks();
// TODO(eseckler): Initialize the entire perfetto client library instead.
perfetto::internal::TrackRegistry::InitializeInstance();
@@ -247,7 +80,7 @@ class TraceEventDataSourceTest : public testing::Test {
auto perfetto_wrapper = std::make_unique<PerfettoTaskRunner>(
task_environment_.GetMainThreadTaskRunner());
producer_client_ =
- std::make_unique<MockProducerClient>(std::move(perfetto_wrapper));
+ std::make_unique<TestProducerClient>(std::move(perfetto_wrapper));
TraceEventMetadataSource::GetInstance()->ResetForTesting();
}
@@ -264,7 +97,7 @@ class TraceEventDataSourceTest : public testing::Test {
wait_for_tracelog_flush.Run();
}
- // As MockTraceWriter keeps a pointer to our MockProducerClient,
+ // As MockTraceWriter keeps a pointer to our TestProducerClient,
// we need to make sure to clean it up from TLS. The other sequences
// get DummyTraceWriters that we don't care about.
TraceEventDataSource::GetInstance()->FlushCurrentThread();
@@ -295,7 +128,7 @@ class TraceEventDataSourceTest : public testing::Test {
}
}
- MockProducerClient* producer_client() { return producer_client_.get(); }
+ TestProducerClient* producer_client() { return producer_client_.get(); }
void ExpectClockSnapshotAndDefaults(
const perfetto::protos::TracePacket* packet,
@@ -305,8 +138,7 @@ class TraceEventDataSourceTest : public testing::Test {
ASSERT_EQ(packet->clock_snapshot().clocks().size(), 3);
EXPECT_EQ(packet->clock_snapshot().clocks()[0].clock_id(),
- static_cast<uint32_t>(
- perfetto::protos::pbzero::ClockSnapshot::Clock::BOOTTIME));
+ static_cast<uint32_t>(kTraceClockId));
EXPECT_FALSE(packet->clock_snapshot().clocks()[0].has_unit_multiplier_ns());
EXPECT_FALSE(packet->clock_snapshot().clocks()[0].has_is_incremental());
@@ -540,9 +372,10 @@ class TraceEventDataSourceTest : public testing::Test {
} else {
EXPECT_EQ(packet->track_event().extra_counter_track_uuids_size(), 0);
if (packet->track_event().extra_counter_values_size()) {
- // If the event is for a different thread, then we shouldn't have thread
- // timestamps except for the explicit thread timestamps above.
+ // If the event is for a different thread or track, we shouldn't have
+ // thread timestamps except for the explicit thread timestamps above.
EXPECT_TRUE(tid_override == 0);
+ EXPECT_EQ(track.uuid, 0u);
int64_t thread_time_delta =
packet->track_event().extra_counter_values()[0];
EXPECT_LE(last_thread_time_ + thread_time_delta,
@@ -735,7 +568,7 @@ class TraceEventDataSourceTest : public testing::Test {
// Should be the first member.
base::test::TaskEnvironment task_environment_;
- std::unique_ptr<MockProducerClient> producer_client_;
+ std::unique_ptr<TestProducerClient> producer_client_;
uint64_t last_timestamp_ = 0;
int64_t last_thread_time_ = 0;
uint64_t default_track_uuid_ = 0u;
@@ -813,7 +646,7 @@ TEST_F(TraceEventDataSourceTest, MetadataGeneratorBeforeTracing) {
metadata_source->StopTracing(wait_for_stop.QuitClosure());
wait_for_stop.Run();
- auto metadata = producer_client()->GetChromeMetadata();
+ auto& metadata = *producer_client()->GetChromeMetadata();
EXPECT_EQ(4, metadata.size());
MetadataHasNamedValue(metadata, "foo_int", 42);
MetadataHasNamedValue(metadata, "foo_str", "bar");
@@ -836,7 +669,7 @@ TEST_F(TraceEventDataSourceTest, MetadataGeneratorWhileTracing) {
metadata_source->StopTracing(wait_for_stop.QuitClosure());
wait_for_stop.Run();
- auto metadata = producer_client()->GetChromeMetadata();
+ auto& metadata = *producer_client()->GetChromeMetadata();
EXPECT_EQ(4, metadata.size());
MetadataHasNamedValue(metadata, "foo_int", 42);
MetadataHasNamedValue(metadata, "foo_str", "bar");
@@ -864,7 +697,7 @@ TEST_F(TraceEventDataSourceTest, MultipleMetadataGenerators) {
metadata_source->StopTracing(wait_for_stop.QuitClosure());
wait_for_stop.Run();
- auto metadata = producer_client()->GetChromeMetadata();
+ auto& metadata = *producer_client()->GetChromeMetadata();
EXPECT_EQ(4, metadata.size());
MetadataHasNamedValue(metadata, "foo_int", 42);
MetadataHasNamedValue(metadata, "foo_str", "bar");
@@ -874,9 +707,9 @@ TEST_F(TraceEventDataSourceTest, MultipleMetadataGenerators) {
child_dict->SetString("child_str", "child_val");
MetadataHasNamedValue(metadata, "child_dict", *child_dict);
- metadata = producer_client()->GetChromeMetadata(1);
- EXPECT_EQ(1, metadata.size());
- MetadataHasNamedValue(metadata, "before_int", 42);
+ auto& metadata1 = *producer_client()->GetChromeMetadata(1);
+ EXPECT_EQ(1, metadata1.size());
+ MetadataHasNamedValue(metadata1, "before_int", 42);
}
TEST_F(TraceEventDataSourceTest, BasicTraceEvent) {
@@ -1686,8 +1519,7 @@ TEST_F(TraceEventDataSourceTest, FilteringMetadataSource) {
metadata_source->StopTracing(wait_for_stop.QuitClosure());
wait_for_stop.Run();
- auto metadata = producer_client()->GetChromeMetadata();
- EXPECT_EQ(0, metadata.size());
+ EXPECT_FALSE(producer_client()->GetChromeMetadata());
}
TEST_F(TraceEventDataSourceTest, ProtoMetadataSource) {
diff --git a/chromium/services/tracing/public/cpp/perfetto/trace_time.h b/chromium/services/tracing/public/cpp/perfetto/trace_time.h
index 4a13d74a316..34a60632258 100644
--- a/chromium/services/tracing/public/cpp/perfetto/trace_time.h
+++ b/chromium/services/tracing/public/cpp/perfetto/trace_time.h
@@ -6,21 +6,21 @@
#define SERVICES_TRACING_PUBLIC_CPP_PERFETTO_TRACE_TIME_H_
#include "build/build_config.h"
-#include "third_party/perfetto/protos/perfetto/trace/clock_snapshot.pbzero.h"
+#include "third_party/perfetto/protos/perfetto/common/builtin_clock.pbzero.h"
namespace tracing {
#if defined(OS_LINUX) || defined(OS_ANDROID) || defined(OS_FUCHSIA)
// Linux, Android, and Fuchsia all use CLOCK_MONOTONIC. See crbug.com/166153
// about efforts to unify base::TimeTicks across all platforms.
-constexpr perfetto::protos::pbzero::ClockSnapshot::Clock::BuiltinClocks
- kTraceClockId = perfetto::protos::pbzero::ClockSnapshot::Clock::MONOTONIC;
+constexpr perfetto::protos::pbzero::BuiltinClock kTraceClockId =
+ perfetto::protos::pbzero::BUILTIN_CLOCK_MONOTONIC;
#else
// Mac and Windows TimeTicks advance when sleeping, so are closest to BOOTTIME
// in behavior.
-// TODO(eseckler): Support specifying Mac/Win platform clocks in BuiltinClocks.
-constexpr perfetto::protos::pbzero::ClockSnapshot::Clock::BuiltinClocks
- kTraceClockId = perfetto::protos::pbzero::ClockSnapshot::Clock::BOOTTIME;
+// TODO(eseckler): Support specifying Mac/Win platform clocks in BuiltinClock.
+constexpr perfetto::protos::pbzero::BuiltinClock kTraceClockId =
+ perfetto::protos::pbzero::BUILTIN_CLOCK_BOOTTIME;
#endif
// Returns CLOCK_BOOTTIME on systems that support it, otherwise falls back to
diff --git a/chromium/services/tracing/public/cpp/perfetto/track_event_thread_local_event_sink.cc b/chromium/services/tracing/public/cpp/perfetto/track_event_thread_local_event_sink.cc
index 90d1696545a..28a678073fb 100644
--- a/chromium/services/tracing/public/cpp/perfetto/track_event_thread_local_event_sink.cc
+++ b/chromium/services/tracing/public/cpp/perfetto/track_event_thread_local_event_sink.cc
@@ -233,6 +233,61 @@ void TrackEventThreadLocalEventSink::ClearIncrementalState() {
incremental_state_reset_id_.fetch_add(1u, std::memory_order_relaxed);
}
+void TrackEventThreadLocalEventSink::AddLegacyTraceEvent(
+ base::trace_event::TraceEvent* trace_event,
+ base::trace_event::TraceEventHandle* handle) {
+ DCHECK(!pending_trace_packet_);
+ UpdateIncrementalStateIfNeeded(trace_event);
+
+ auto trace_packet = trace_writer_->NewTracePacket();
+ PrepareTrackEvent(trace_event, handle, &trace_packet);
+
+ if (!pending_interning_updates_.empty()) {
+ EmitStoredInternedData(trace_packet->set_interned_data());
+ }
+}
+
+base::trace_event::TrackEventHandle
+TrackEventThreadLocalEventSink::AddTypedTraceEvent(
+ base::trace_event::TraceEvent* trace_event) {
+ DCHECK(!TraceEventDataSource::GetInstance()
+ ->GetThreadIsInTraceEventTLS()
+ ->Get());
+ // Cleared in OnTrackEventCompleted().
+ TraceEventDataSource::GetInstance()->GetThreadIsInTraceEventTLS()->Set(true);
+
+ DCHECK(!pending_trace_packet_);
+ UpdateIncrementalStateIfNeeded(trace_event);
+
+ pending_trace_packet_ = trace_writer_->NewTracePacket();
+
+ // Note: Since |track_event| is a protozero message under |trace_packet|, we
+ // can't modify |trace_packet| further until we're done with |track_event|.
+ // Thus, incremental state is buffered until the TrackEventHandle we return
+ // here is destroyed.
+ base::trace_event::TraceEventHandle base_handle{0, 0, 0};
+ auto* track_event =
+ PrepareTrackEvent(trace_event, &base_handle, &pending_trace_packet_);
+
+ // |pending_trace_packet_| will be finalized in OnTrackEventCompleted() after
+ // the code in //base ran the typed trace point's argument function.
+ return base::trace_event::TrackEventHandle(track_event, this);
+}
+
+void TrackEventThreadLocalEventSink::OnTrackEventCompleted() {
+ DCHECK(pending_trace_packet_);
+
+ if (!pending_interning_updates_.empty()) {
+ EmitStoredInternedData(pending_trace_packet_->set_interned_data());
+ }
+
+ pending_trace_packet_ = perfetto::TraceWriter::TracePacketHandle();
+
+ DCHECK(
+ TraceEventDataSource::GetInstance()->GetThreadIsInTraceEventTLS()->Get());
+ TraceEventDataSource::GetInstance()->GetThreadIsInTraceEventTLS()->Set(false);
+}
+
void TrackEventThreadLocalEventSink::UpdateIncrementalStateIfNeeded(
base::trace_event::TraceEvent* trace_event) {
bool explicit_timestamp =
@@ -785,9 +840,7 @@ void TrackEventThreadLocalEventSink::UpdateDuration(
trace_event_internal::kNoId /* bind_id */, nullptr,
explicit_timestamps ? TRACE_EVENT_FLAG_EXPLICIT_TIMESTAMP
: TRACE_EVENT_FLAG_NONE);
- perfetto::Track track{};
- AddTraceEvent(&new_trace_event, nullptr, track,
- [](perfetto::EventContext) {});
+ AddLegacyTraceEvent(&new_trace_event, nullptr);
}
void TrackEventThreadLocalEventSink::Flush() {
@@ -915,20 +968,10 @@ void TrackEventThreadLocalEventSink::DoResetIncrementalState(
}
ClockSnapshot* clocks = packet->set_clock_snapshot();
- // Always reference the boottime timestamps to help trace processor
- // translate the clocks to boottime more efficiently.
+ // Reference clock is in nanoseconds.
ClockSnapshot::Clock* clock_reference = clocks->add_clocks();
- clock_reference->set_clock_id(ClockSnapshot::Clock::BOOTTIME);
- if (kTraceClockId == ClockSnapshot::Clock::BOOTTIME) {
- clock_reference->set_timestamp(timestamp.since_origin().InNanoseconds());
- } else {
- int64_t current_boot_nanos = TraceBootTicksNow();
- int64_t current_monotonic_nanos =
- TRACE_TIME_TICKS_NOW().since_origin().InNanoseconds();
- int64_t diff = current_boot_nanos - current_monotonic_nanos;
- clock_reference->set_timestamp(timestamp.since_origin().InNanoseconds() +
- diff);
- }
+ clock_reference->set_clock_id(kTraceClockId);
+ clock_reference->set_timestamp(timestamp.since_origin().InNanoseconds());
// Absolute clock in micros.
ClockSnapshot::Clock* clock_absolute = clocks->add_clocks();
clock_absolute->set_clock_id(kClockIdAbsolute);
diff --git a/chromium/services/tracing/public/cpp/perfetto/track_event_thread_local_event_sink.h b/chromium/services/tracing/public/cpp/perfetto/track_event_thread_local_event_sink.h
index a3ff3bbb897..0b3095b72e8 100644
--- a/chromium/services/tracing/public/cpp/perfetto/track_event_thread_local_event_sink.h
+++ b/chromium/services/tracing/public/cpp/perfetto/track_event_thread_local_event_sink.h
@@ -16,6 +16,8 @@
#include "base/threading/thread_id_name_manager.h"
#include "base/time/time.h"
#include "base/trace_event/thread_instruction_count.h"
+#include "base/trace_event/typed_macros.h"
+#include "base/trace_event/typed_macros_embedder_support.h"
#include "services/tracing/public/cpp/perfetto/interning_index.h"
#include "third_party/perfetto/include/perfetto/ext/tracing/core/trace_writer.h"
#include "third_party/perfetto/include/perfetto/protozero/message_handle.h"
@@ -29,7 +31,8 @@ namespace tracing {
// ThreadLocalEventSink that emits TrackEvent protos.
class COMPONENT_EXPORT(TRACING_CPP) TrackEventThreadLocalEventSink
- : public base::ThreadIdNameManager::Observer {
+ : public base::ThreadIdNameManager::Observer,
+ public base::trace_event::TrackEventHandle::CompletionListener {
public:
enum class IndexType {
kName = 0,
@@ -67,51 +70,11 @@ class COMPONENT_EXPORT(TRACING_CPP) TrackEventThreadLocalEventSink
// (e.g. interning index entries and a ThreadDescriptor) to be emitted again.
static void ClearIncrementalState();
- // Emit any necessary descriptors that we haven't emitted yet and, if
- // required, perform an incremental state reset.
- void UpdateIncrementalStateIfNeeded(
- base::trace_event::TraceEvent* trace_event);
-
- // Fills in all the fields in |trace_packet| that can be directly deduced from
- // |trace_event|. Also fills all updates needed to be emitted into the
- // |InternedData| field into |pending_interning_updates_|. Returns a pointer
- // to the prepared TrackEvent proto, on which the caller may set further
- // fields.
- perfetto::protos::pbzero::TrackEvent* PrepareTrackEvent(
- base::trace_event::TraceEvent* trace_event,
- base::trace_event::TraceEventHandle* handle,
- protozero::MessageHandle<perfetto::protos::pbzero::TracePacket>*
- trace_packet);
-
- // Given a list of updates to the indexes will fill in |interned_data| to
- // reflect them.
- void EmitStoredInternedData(
- perfetto::protos::pbzero::InternedData* interned_data);
-
- template <
- typename TrackEventArgumentFunction = void (*)(perfetto::EventContext)>
- void AddTraceEvent(base::trace_event::TraceEvent* trace_event,
- base::trace_event::TraceEventHandle* handle,
- const perfetto::Track& track,
- TrackEventArgumentFunction arg_func) {
- UpdateIncrementalStateIfNeeded(trace_event);
-
- auto trace_packet = trace_writer_->NewTracePacket();
-
- // Note: Since |track_event| is a protozero message under |trace_packet|, we
- // can't modify |trace_packet| further until we're done with |track_event|.
- auto* track_event = PrepareTrackEvent(trace_event, handle, &trace_packet);
-
- if (track) {
- track_event->set_track_uuid(track.uuid);
- }
-
- arg_func(perfetto::EventContext(track_event));
+ void AddLegacyTraceEvent(base::trace_event::TraceEvent* trace_event,
+ base::trace_event::TraceEventHandle* handle);
- if (!pending_interning_updates_.empty()) {
- EmitStoredInternedData(trace_packet->set_interned_data());
- }
- }
+ base::trace_event::TrackEventHandle AddTypedTraceEvent(
+ base::trace_event::TraceEvent* trace_event);
void UpdateDuration(
const unsigned char* category_group_enabled,
@@ -129,9 +92,33 @@ class COMPONENT_EXPORT(TRACING_CPP) TrackEventThreadLocalEventSink
// ThreadIdNameManager::Observer implementation:
void OnThreadNameChanged(const char* name) override;
+ // base::trace_event::TrackEventHandle::CompletionListener implementation:
+ void OnTrackEventCompleted() override;
+
private:
static constexpr size_t kMaxCompleteEventDepth = 30;
+ // Emit any necessary descriptors that we haven't emitted yet and, if
+ // required, perform an incremental state reset.
+ void UpdateIncrementalStateIfNeeded(
+ base::trace_event::TraceEvent* trace_event);
+
+ // Fills in all the fields in |trace_packet| that can be directly deduced from
+ // |trace_event|. Also fills all updates needed to be emitted into the
+ // |InternedData| field into |pending_interning_updates_|. Returns a pointer
+ // to the prepared TrackEvent proto, on which the caller may set further
+ // fields.
+ perfetto::protos::pbzero::TrackEvent* PrepareTrackEvent(
+ base::trace_event::TraceEvent* trace_event,
+ base::trace_event::TraceEventHandle* handle,
+ protozero::MessageHandle<perfetto::protos::pbzero::TracePacket>*
+ trace_packet);
+
+ // Given a list of updates to the indexes will fill in |interned_data| to
+ // reflect them.
+ void EmitStoredInternedData(
+ perfetto::protos::pbzero::InternedData* interned_data);
+
void EmitThreadTrackDescriptor(base::trace_event::TraceEvent* trace_event,
base::TimeTicks timestamp,
const char* maybe_new_name = nullptr);
@@ -186,6 +173,11 @@ class COMPONENT_EXPORT(TRACING_CPP) TrackEventThreadLocalEventSink
uint32_t session_id_;
bool disable_interning_;
uint32_t sink_id_;
+
+ // Stores the trace packet handle for a typed TrackEvent until the TrackEvent
+ // was finalized after the code in //base filled its typed argument fields.
+ perfetto::TraceWriter::TracePacketHandle pending_trace_packet_;
+
DISALLOW_COPY_AND_ASSIGN(TrackEventThreadLocalEventSink);
};