summaryrefslogtreecommitdiff
path: root/chromium/services/tracing
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
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')
-rw-r--r--chromium/services/tracing/BUILD.gn3
-rw-r--r--chromium/services/tracing/DEPS5
-rw-r--r--chromium/services/tracing/perfetto/consumer_host.cc10
-rw-r--r--chromium/services/tracing/perfetto/perfetto_service.h1
-rw-r--r--chromium/services/tracing/perfetto/privacy_filtered_fields-inl.h25
-rw-r--r--chromium/services/tracing/perfetto/system_perfetto_unittest.cc79
-rw-r--r--chromium/services/tracing/public/cpp/BUILD.gn25
-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
-rw-r--r--chromium/services/tracing/public/cpp/stack_sampling/reached_code_data_source_android.cc71
-rw-r--r--chromium/services/tracing/public/cpp/stack_sampling/reached_code_data_source_android.h42
-rw-r--r--chromium/services/tracing/public/cpp/stack_sampling/reached_code_data_source_android_unittest.cc104
-rw-r--r--chromium/services/tracing/public/cpp/stack_sampling/tracing_sampler_profiler.cc4
-rw-r--r--chromium/services/tracing/public/cpp/stack_sampling/tracing_sampler_profiler_unittest.cc189
-rw-r--r--chromium/services/tracing/public/cpp/trace_event_agent.cc13
-rw-r--r--chromium/services/tracing/public/cpp/trace_event_args_allowlist.cc (renamed from chromium/services/tracing/public/cpp/trace_event_args_whitelist.cc)49
-rw-r--r--chromium/services/tracing/public/cpp/trace_event_args_allowlist.h (renamed from chromium/services/tracing/public/cpp/trace_event_args_whitelist.h)14
-rw-r--r--chromium/services/tracing/public/cpp/trace_startup.cc2
-rw-r--r--chromium/services/tracing/public/mojom/perfetto_service.mojom2
34 files changed, 1014 insertions, 928 deletions
diff --git a/chromium/services/tracing/BUILD.gn b/chromium/services/tracing/BUILD.gn
index 65fad54a857..bcb2fe7993d 100644
--- a/chromium/services/tracing/BUILD.gn
+++ b/chromium/services/tracing/BUILD.gn
@@ -82,9 +82,12 @@ source_set("tests") {
"perfetto/perfetto_integration_unittest.cc",
"public/cpp/perfetto/java_heap_profiler/hprof_buffer_android_unittest.cc",
"public/cpp/perfetto/java_heap_profiler/hprof_parser_android_unittest.cc",
+ "public/cpp/perfetto/producer_test_utils.cc",
+ "public/cpp/perfetto/producer_test_utils.h",
"public/cpp/perfetto/task_runner_unittest.cc",
"public/cpp/perfetto/trace_event_data_source_unittest.cc",
"public/cpp/perfetto/traced_value_proto_writer_unittest.cc",
+ "public/cpp/stack_sampling/reached_code_data_source_android_unittest.cc",
"public/cpp/stack_sampling/tracing_sampler_profiler_unittest.cc",
]
diff --git a/chromium/services/tracing/DEPS b/chromium/services/tracing/DEPS
index 744fe92bc54..fcde8ac081b 100644
--- a/chromium/services/tracing/DEPS
+++ b/chromium/services/tracing/DEPS
@@ -9,9 +9,4 @@ specific_include_rules = {
'stack_unwinder_android_unittest.cc': [
"+services/tracing/jni_headers",
],
- # Temporary to research https://crbug.com/1074115
- # TODO(crbug.com/1074115): Remove this
- 'producer_client.cc': [
- "+components/crash/core/app/crashpad.h",
- ],
}
diff --git a/chromium/services/tracing/perfetto/consumer_host.cc b/chromium/services/tracing/perfetto/consumer_host.cc
index f6cb275cf51..67a3d1b0e0f 100644
--- a/chromium/services/tracing/perfetto/consumer_host.cc
+++ b/chromium/services/tracing/perfetto/consumer_host.cc
@@ -26,7 +26,7 @@
#include "mojo/public/cpp/bindings/strong_binding.h"
#include "mojo/public/cpp/system/wait.h"
#include "services/tracing/perfetto/perfetto_service.h"
-#include "services/tracing/public/cpp/trace_event_args_whitelist.h"
+#include "services/tracing/public/cpp/trace_event_args_allowlist.h"
#include "third_party/perfetto/include/perfetto/ext/trace_processor/export_json.h"
#include "third_party/perfetto/include/perfetto/ext/tracing/core/observable_events.h"
#include "third_party/perfetto/include/perfetto/ext/tracing/core/slice.h"
@@ -382,9 +382,9 @@ void ConsumerHost::TracingSession::DisableTracingAndEmitJson(
base::SequencedTaskRunnerHandle::Get());
if (privacy_filtering_enabled) {
- // For filtering/whitelisting to be possible at JSON export time,
+ // For filtering/allowlisting to be possible at JSON export time,
// filtering must not have been enabled during proto emission time
- // (or there's nothing to pass through the whitelist).
+ // (or there's nothing to pass through the allowlist).
DCHECK(!privacy_filtering_enabled_);
privacy_filtering_enabled_ = true;
}
@@ -408,9 +408,9 @@ void ConsumerHost::TracingSession::ExportJson() {
->GetArgumentFilterPredicate()
.is_null()) {
base::trace_event::TraceLog::GetInstance()->SetArgumentFilterPredicate(
- base::BindRepeating(&IsTraceEventArgsWhitelisted));
+ base::BindRepeating(&IsTraceEventArgsAllowlisted));
base::trace_event::TraceLog::GetInstance()->SetMetadataFilterPredicate(
- base::BindRepeating(&IsMetadataWhitelisted));
+ base::BindRepeating(&IsMetadataAllowlisted));
}
perfetto::trace_processor::json::ArgumentFilterPredicate argument_filter;
diff --git a/chromium/services/tracing/perfetto/perfetto_service.h b/chromium/services/tracing/perfetto/perfetto_service.h
index a54618ff0e8..edba7d6ab58 100644
--- a/chromium/services/tracing/perfetto/perfetto_service.h
+++ b/chromium/services/tracing/perfetto/perfetto_service.h
@@ -11,7 +11,6 @@
#include "base/macros.h"
#include "mojo/public/cpp/bindings/receiver_set.h"
-#include "mojo/public/cpp/bindings/strong_binding_set.h"
#include "mojo/public/cpp/bindings/unique_receiver_set.h"
#include "services/tracing/perfetto/consumer_host.h"
#include "services/tracing/public/cpp/perfetto/task_runner.h"
diff --git a/chromium/services/tracing/perfetto/privacy_filtered_fields-inl.h b/chromium/services/tracing/perfetto/privacy_filtered_fields-inl.h
index d7433465e08..3982a6823fb 100644
--- a/chromium/services/tracing/perfetto/privacy_filtered_fields-inl.h
+++ b/chromium/services/tracing/perfetto/privacy_filtered_fields-inl.h
@@ -30,8 +30,10 @@ constexpr int kClockIndices[] = {1, 2, 3, 4, -1};
constexpr MessageInfo kClock = {kClockIndices, nullptr};
// Proto Message: ClockSnapshot
-constexpr int kClockSnapshotIndices[] = {1, -1};
-constexpr MessageInfo const* kClockSnapshotComplexMessages[] = {&kClock};
+// Manually allowlisted: 2 (primary_trace_clock).
+constexpr int kClockSnapshotIndices[] = {1, 2, -1};
+constexpr MessageInfo const* kClockSnapshotComplexMessages[] = {&kClock,
+ nullptr};
constexpr MessageInfo kClockSnapshot = {kClockSnapshotIndices,
kClockSnapshotComplexMessages};
@@ -154,15 +156,21 @@ constexpr int kComponentInfoIndices[] = {1, 2, -1};
constexpr MessageInfo kComponentInfo = {kComponentInfoIndices, nullptr};
// Proto Message: ChromeLatencyInfo
-constexpr int kChromeLatencyInfoIndices[] = {1, 2, 3, 4, 5, -1};
+constexpr int kChromeLatencyInfoIndices[] = {1, 2, 3, 4, 5, 6, -1};
constexpr MessageInfo const* kChromeLatencyInfoComplexMessages[] = {
- nullptr, nullptr, nullptr, &kComponentInfo, nullptr};
+ nullptr, nullptr, nullptr, &kComponentInfo, nullptr, nullptr};
constexpr MessageInfo kChromeLatencyInfo = {kChromeLatencyInfoIndices,
kChromeLatencyInfoComplexMessages};
+// Proto Message: ChromeFrameReporter
+constexpr int kChromeFrameReporterIndices[] = {1, 2, 3, 4, -1};
+constexpr MessageInfo kChromeFrameReporter = {kChromeFrameReporterIndices,
+ nullptr};
+
// Proto Message: TrackEvent
-constexpr int kTrackEventIndices[] = {1, 2, 3, 5, 6, 9, 10, 11, 12, 16,
- 17, 24, 25, 26, 27, 28, 29, 30, 31, -1};
+constexpr int kTrackEventIndices[] = {1, 2, 3, 5, 6, 9, 10,
+ 11, 12, 16, 17, 24, 25, 26,
+ 27, 28, 29, 30, 31, 32, -1};
constexpr MessageInfo const* kTrackEventComplexMessages[] = {
nullptr,
nullptr,
@@ -182,7 +190,8 @@ constexpr MessageInfo const* kTrackEventComplexMessages[] = {
&kChromeHistogramSample,
&kChromeLatencyInfo,
nullptr,
- nullptr};
+ nullptr,
+ &kChromeFrameReporter};
constexpr MessageInfo kTrackEvent = {kTrackEventIndices,
kTrackEventComplexMessages};
@@ -344,7 +353,7 @@ constexpr MessageInfo kTrackDescriptor = {kTrackDescriptorIndices,
kTrackDescriptorComplexMessages};
// Proto Message: TracePacket
-// EDIT: Manually whitelisted: 3 (trusted_uid).
+// EDIT: Manually allowlisted: 3 (trusted_uid).
constexpr int kTracePacketIndices[] = {3, 6, 8, 10, 11, 12, 13, 35, 36, 41,
42, 43, 44, 51, 54, 56, 58, 59, 60, -1};
constexpr MessageInfo const* kTracePacketComplexMessages[] = {
diff --git a/chromium/services/tracing/perfetto/system_perfetto_unittest.cc b/chromium/services/tracing/perfetto/system_perfetto_unittest.cc
index 1e660c1a21f..f217e6d0103 100644
--- a/chromium/services/tracing/perfetto/system_perfetto_unittest.cc
+++ b/chromium/services/tracing/perfetto/system_perfetto_unittest.cc
@@ -933,5 +933,84 @@ TEST_F(SystemPerfettoTest, RespectsFeatureList) {
->IsDummySystemProducerForTesting());
}
}
+
+#if defined(OS_ANDROID)
+TEST_F(SystemPerfettoTest, RespectsFeaturePreAndroidPie) {
+ if (base::android::BuildInfo::GetInstance()->sdk_int() >=
+ base::android::SDK_VERSION_P) {
+ return;
+ }
+
+ auto run_test = [this](bool enable_feature) {
+ PerfettoTracedProcess::Get()->ClearDataSourcesForTesting();
+
+ base::test::ScopedFeatureList feature_list;
+ if (enable_feature) {
+ feature_list.InitAndEnableFeature(features::kEnablePerfettoSystemTracing);
+ } else {
+ feature_list.InitAndDisableFeature(
+ features::kEnablePerfettoSystemTracing);
+ }
+ PerfettoTracedProcess::ReconstructForTesting(producer_socket_.c_str());
+
+ std::string data_source_name = "temp_name";
+
+ base::RunLoop data_source_started_runloop;
+ std::unique_ptr<TestDataSource> data_source =
+ TestDataSource::CreateAndRegisterDataSource(data_source_name, 1);
+ data_source->set_start_tracing_callback(
+ data_source_started_runloop.QuitClosure());
+
+ auto system_service = CreateMockSystemService();
+
+ base::RunLoop system_no_more_packets_runloop;
+ MockConsumer system_consumer(
+ {data_source_name}, system_service->GetService(),
+ [&system_no_more_packets_runloop](bool has_more) {
+ if (!has_more) {
+ system_no_more_packets_runloop.Quit();
+ }
+ });
+
+ base::RunLoop system_data_source_enabled_runloop;
+ base::RunLoop system_data_source_disabled_runloop;
+ auto system_producer = CreateMockPosixSystemProducer(
+ system_service.get(),
+ /* num_data_sources = */ 1, &system_data_source_enabled_runloop,
+ &system_data_source_disabled_runloop, /* check_sdk_level = */ true);
+ PerfettoTracedProcess::GetTaskRunner()->PostTask(
+ [&system_producer]() { system_producer->ConnectToSystemService(); });
+
+ if (enable_feature) {
+ system_data_source_enabled_runloop.Run();
+ data_source_started_runloop.Run();
+ system_consumer.WaitForAllDataSourcesStarted();
+ }
+
+ // Post the task to ensure that the data will have been written and
+ // committed if any tracing is being done.
+ base::RunLoop stop_tracing;
+ PerfettoTracedProcess::GetTaskRunner()->PostTask(
+ [&system_consumer, &stop_tracing]() {
+ system_consumer.StopTracing();
+ stop_tracing.Quit();
+ });
+ stop_tracing.Run();
+
+ if (enable_feature) {
+ system_data_source_disabled_runloop.Run();
+ system_consumer.WaitForAllDataSourcesStopped();
+ }
+ system_no_more_packets_runloop.Run();
+
+ PerfettoProducer::DeleteSoonForTesting(std::move(system_producer));
+ return system_consumer.received_test_packets();
+ };
+
+ EXPECT_EQ(1u, run_test(/* enable_feature = */ true));
+ EXPECT_EQ(0u, run_test(/* enable_feature = */ false));
+}
+#endif // defined(OS_ANDROID)
+
} // namespace
} // namespace tracing
diff --git a/chromium/services/tracing/public/cpp/BUILD.gn b/chromium/services/tracing/public/cpp/BUILD.gn
index f94537ea640..1cd4d42da6e 100644
--- a/chromium/services/tracing/public/cpp/BUILD.gn
+++ b/chromium/services/tracing/public/cpp/BUILD.gn
@@ -2,10 +2,10 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-import("//base/trace_event/features.gni")
import("//build/buildflag_header.gni")
import("//build/config/chromecast_build.gni")
import("//build/config/compiler/compiler.gni")
+import("//build_overrides/build.gni")
import("//services/tracing/public/cpp/stack_sampling/loader_lock_sampling.gni")
buildflag_header("buildflags") {
@@ -40,8 +40,9 @@ if (!is_nacl && !is_ios) {
target(tracing_lib_type, "cpp") {
sources = [
+ "perfetto/flow_event_utils.cc",
+ "perfetto/flow_event_utils.h",
"perfetto/macros.h",
- "perfetto/macros_internal.h",
]
defines = [ "IS_TRACING_CPP_IMPL" ]
@@ -49,14 +50,11 @@ target(tracing_lib_type, "cpp") {
configs += [ "//build/config/compiler:wexit_time_destructors" ]
- public_deps = [
- "//base",
- "//third_party/perfetto:libperfetto",
- ]
+ public_deps = [ "//base" ]
deps = [ "//third_party/perfetto/include/perfetto/protozero" ]
- all_dependent_configs = [ "//third_party/perfetto/gn:public_config" ]
+ all_dependent_configs = []
if (!is_nacl && !is_ios) {
sources += [
@@ -64,8 +62,6 @@ target(tracing_lib_type, "cpp") {
"base_agent.h",
"perfetto/dummy_producer.cc",
"perfetto/dummy_producer.h",
- "perfetto/flow_event_utils.cc",
- "perfetto/flow_event_utils.h",
"perfetto/interning_index.h",
"perfetto/java_heap_profiler/hprof_buffer_android.cc",
"perfetto/java_heap_profiler/hprof_buffer_android.h",
@@ -76,7 +72,6 @@ target(tracing_lib_type, "cpp") {
"perfetto/java_heap_profiler/hprof_parser_android.h",
"perfetto/java_heap_profiler/java_heap_profiler_android.cc",
"perfetto/java_heap_profiler/java_heap_profiler_android.h",
- "perfetto/macros_internal.cc",
"perfetto/perfetto_config.cc",
"perfetto/perfetto_config.h",
"perfetto/perfetto_producer.cc",
@@ -100,12 +95,14 @@ target(tracing_lib_type, "cpp") {
"perfetto/traced_value_proto_writer.h",
"perfetto/track_event_thread_local_event_sink.cc",
"perfetto/track_event_thread_local_event_sink.h",
+ "stack_sampling/reached_code_data_source_android.cc",
+ "stack_sampling/reached_code_data_source_android.h",
"stack_sampling/tracing_sampler_profiler.cc",
"stack_sampling/tracing_sampler_profiler.h",
"trace_event_agent.cc",
"trace_event_agent.h",
- "trace_event_args_whitelist.cc",
- "trace_event_args_whitelist.h",
+ "trace_event_args_allowlist.cc",
+ "trace_event_args_allowlist.h",
"trace_startup.cc",
"trace_startup.h",
"traced_process_impl.cc",
@@ -141,10 +138,6 @@ target(tracing_lib_type, "cpp") {
]
}
- if (is_linux && !is_fuchsia) {
- deps += [ "//components/crash/core/app:app" ]
- }
-
if (is_android && can_unwind_with_cfi_table && is_official_build) {
sources += [
"stack_sampling/stack_sampler_android.cc",
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);
};
diff --git a/chromium/services/tracing/public/cpp/stack_sampling/reached_code_data_source_android.cc b/chromium/services/tracing/public/cpp/stack_sampling/reached_code_data_source_android.cc
new file mode 100644
index 00000000000..8d423d93a89
--- /dev/null
+++ b/chromium/services/tracing/public/cpp/stack_sampling/reached_code_data_source_android.cc
@@ -0,0 +1,71 @@
+// 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/stack_sampling/reached_code_data_source_android.h"
+
+#include <utility>
+#include <vector>
+
+#include "base/android/reached_addresses_bitset.h"
+#include "base/android/reached_code_profiler.h"
+#include "services/tracing/public/cpp/perfetto/perfetto_producer.h"
+#include "third_party/perfetto/include/perfetto/tracing/data_source.h"
+#include "third_party/perfetto/protos/perfetto/trace/profiling/profile_packet.pbzero.h"
+#include "third_party/perfetto/protos/perfetto/trace/trace_packet.pbzero.h"
+
+namespace tracing {
+
+// static
+ReachedCodeDataSource* ReachedCodeDataSource::Get() {
+ static base::NoDestructor<ReachedCodeDataSource> instance;
+ return instance.get();
+}
+
+ReachedCodeDataSource::ReachedCodeDataSource()
+ : DataSourceBase(mojom::kReachedCodeProfilerSourceName) {}
+
+ReachedCodeDataSource::~ReachedCodeDataSource() {
+ NOTREACHED();
+}
+
+void ReachedCodeDataSource::StartTracing(
+ PerfettoProducer* producer,
+ const perfetto::DataSourceConfig& data_source_config) {
+ trace_writer_ =
+ producer->CreateTraceWriter(data_source_config.target_buffer());
+}
+
+void ReachedCodeDataSource::StopTracing(
+ base::OnceClosure stop_complete_callback) {
+ if (!base::android::IsReachedCodeProfilerEnabled()) {
+ std::move(stop_complete_callback).Run();
+ return;
+ }
+ auto* bitset = base::android::ReachedAddressesBitset::GetTextBitset();
+ // |bitset| is null when the build does not support code ordering.
+ if (!bitset) {
+ return;
+ }
+ std::vector<uint32_t> offsets = bitset->GetReachedOffsets();
+ perfetto::TraceWriter::TracePacketHandle trace_packet =
+ trace_writer_->NewTracePacket();
+ // Delta encoded timestamps and interned data require incremental state.
+ auto* streaming_profile_packet = trace_packet->set_streaming_profile_packet();
+ for (uint32_t offset : offsets) {
+ // TODO(ssid): add a new packed field to the trace packet proto.
+ streaming_profile_packet->add_callstack_iid(offset);
+ }
+ trace_packet->Finalize();
+ trace_writer_.reset();
+ std::move(stop_complete_callback).Run();
+}
+
+void ReachedCodeDataSource::Flush(
+ base::RepeatingClosure flush_complete_callback) {
+ flush_complete_callback.Run();
+}
+
+void ReachedCodeDataSource::ClearIncrementalState() {}
+
+} // namespace tracing
diff --git a/chromium/services/tracing/public/cpp/stack_sampling/reached_code_data_source_android.h b/chromium/services/tracing/public/cpp/stack_sampling/reached_code_data_source_android.h
new file mode 100644
index 00000000000..73c615d94c8
--- /dev/null
+++ b/chromium/services/tracing/public/cpp/stack_sampling/reached_code_data_source_android.h
@@ -0,0 +1,42 @@
+// 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_STACK_SAMPLING_REACHED_CODE_DATA_SOURCE_ANDROID_H_
+#define SERVICES_TRACING_PUBLIC_CPP_STACK_SAMPLING_REACHED_CODE_DATA_SOURCE_ANDROID_H_
+
+#include <memory>
+
+#include "base/component_export.h"
+#include "services/tracing/public/cpp/perfetto/perfetto_traced_process.h"
+#include "third_party/perfetto/include/perfetto/ext/tracing/core/trace_writer.h"
+
+namespace tracing {
+
+class COMPONENT_EXPORT(TRACING_CPP) ReachedCodeDataSource
+ : public PerfettoTracedProcess::DataSourceBase {
+ public:
+ static ReachedCodeDataSource* Get();
+
+ ReachedCodeDataSource();
+ ~ReachedCodeDataSource() override;
+
+ // PerfettoTracedProcess::DataSourceBase implementation, called by
+ // ProducerClient.
+ void StartTracing(
+ PerfettoProducer* producer,
+ const perfetto::DataSourceConfig& data_source_config) override;
+ void StopTracing(base::OnceClosure stop_complete_callback) override;
+ void Flush(base::RepeatingClosure flush_complete_callback) override;
+ void ClearIncrementalState() override;
+
+ ReachedCodeDataSource(ReachedCodeDataSource&&) = delete;
+ ReachedCodeDataSource& operator=(ReachedCodeDataSource&&) = delete;
+
+ private:
+ std::unique_ptr<perfetto::TraceWriter> trace_writer_;
+};
+
+} // namespace tracing
+
+#endif // SERVICES_TRACING_PUBLIC_CPP_STACK_SAMPLING_REACHED_CODE_DATA_SOURCE_ANDROID_H_
diff --git a/chromium/services/tracing/public/cpp/stack_sampling/reached_code_data_source_android_unittest.cc b/chromium/services/tracing/public/cpp/stack_sampling/reached_code_data_source_android_unittest.cc
new file mode 100644
index 00000000000..5cf87745ba6
--- /dev/null
+++ b/chromium/services/tracing/public/cpp/stack_sampling/reached_code_data_source_android_unittest.cc
@@ -0,0 +1,104 @@
+// 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/stack_sampling/reached_code_data_source_android.h"
+
+#include <stdlib.h>
+
+#include <limits>
+#include <memory>
+#include <utility>
+
+#include "base/android/reached_code_profiler.h"
+#include "base/base_switches.h"
+#include "base/bind_helpers.h"
+#include "base/run_loop.h"
+#include "base/test/task_environment.h"
+#include "base/time/time.h"
+#include "services/tracing/public/cpp/perfetto/producer_test_utils.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/perfetto/include/perfetto/tracing/core/forward_decls.h"
+
+namespace tracing {
+
+namespace {
+
+double BusyLoopFor(base::TimeDelta duration) {
+ // Do some floating point arithmetic, since uninterruptible waits cannot be
+ // profiled.
+ base::TimeTicks end = base::TimeTicks::Now() + duration;
+ double number = 1;
+ while (base::TimeTicks::Now() < end) {
+ for (int i = 0; i < 10000; ++i) {
+ number *= rand() / static_cast<double>(RAND_MAX) * 2;
+ }
+ }
+ return number;
+}
+
+class ReachedCodeDataSourceTest : public testing::Test {
+ public:
+ void SetUp() override {
+ PerfettoTracedProcess::ResetTaskRunnerForTesting();
+ PerfettoTracedProcess::GetTaskRunner()->GetOrCreateTaskRunner();
+
+ auto perfetto_wrapper = std::make_unique<PerfettoTaskRunner>(
+ task_environment_.GetMainThreadTaskRunner());
+
+ producer_ =
+ std::make_unique<TestProducerClient>(std::move(perfetto_wrapper));
+ }
+
+ void TearDown() override {
+ // Be sure there is no pending/running tasks.
+ task_environment_.RunUntilIdle();
+ }
+
+ void BeginTrace() {
+ ReachedCodeDataSource::Get()->StartTracingWithID(
+ /*data_source_id=*/1, producer_.get(), perfetto::DataSourceConfig());
+ }
+
+ void EndTracing() {
+ base::RunLoop wait_for_end;
+ ReachedCodeDataSource::Get()->StopTracing(wait_for_end.QuitClosure());
+ wait_for_end.Run();
+ }
+
+ TestProducerClient* producer() const { return producer_.get(); }
+
+ private:
+ base::test::TaskEnvironment task_environment_;
+
+ std::unique_ptr<TestProducerClient> producer_;
+};
+
+} // namespace
+
+TEST_F(ReachedCodeDataSourceTest, ProfilerDisabled) {
+ BeginTrace();
+ base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(200));
+ EndTracing();
+ EXPECT_EQ(producer()->GetFinalizedPacketCount(), 0u);
+}
+
+TEST_F(ReachedCodeDataSourceTest, ProfilerOutput) {
+ if (!base::android::IsReachedCodeProfilerSupported())
+ return;
+ base::CommandLine::ForCurrentProcess()->AppendSwitch(
+ switches::kEnableReachedCodeProfiler);
+ base::android::InitReachedCodeProfilerAtStartup(
+ base::android::PROCESS_BROWSER);
+ ASSERT_TRUE(base::android::IsReachedCodeProfilerEnabled());
+ BeginTrace();
+ BusyLoopFor(base::TimeDelta::FromSeconds(2));
+ EndTracing();
+ EXPECT_EQ(producer()->GetFinalizedPacketCount(), 1u);
+ const auto* packet = producer()->GetFinalizedPacket();
+ EXPECT_TRUE(packet->has_streaming_profile_packet());
+ // TODO: the profiler doesn't work in test because of ordering.
+ EXPECT_GT(packet->streaming_profile_packet().callstack_iid_size(), 0);
+}
+
+} // namespace tracing
diff --git a/chromium/services/tracing/public/cpp/stack_sampling/tracing_sampler_profiler.cc b/chromium/services/tracing/public/cpp/stack_sampling/tracing_sampler_profiler.cc
index fc86e4f5009..b99bda52188 100644
--- a/chromium/services/tracing/public/cpp/stack_sampling/tracing_sampler_profiler.cc
+++ b/chromium/services/tracing/public/cpp/stack_sampling/tracing_sampler_profiler.cc
@@ -652,10 +652,6 @@ void TracingSamplerProfiler::StartTracing(
base::StackSamplingProfiler::SamplingParams params;
params.samples_per_profile = std::numeric_limits<int>::max();
params.sampling_interval = base::TimeDelta::FromMilliseconds(50);
- // If the sampled thread is stopped for too long for sampling then it is ok to
- // get next sample at a later point of time. We do not want very accurate
- // metrics when looking at traces.
- params.keep_consistent_sampling_interval = false;
auto profile_builder = std::make_unique<TracingProfileBuilder>(
sampled_thread_token_.id, std::move(trace_writer),
diff --git a/chromium/services/tracing/public/cpp/stack_sampling/tracing_sampler_profiler_unittest.cc b/chromium/services/tracing/public/cpp/stack_sampling/tracing_sampler_profiler_unittest.cc
index 0be58031175..f619fa85099 100644
--- a/chromium/services/tracing/public/cpp/stack_sampling/tracing_sampler_profiler_unittest.cc
+++ b/chromium/services/tracing/public/cpp/stack_sampling/tracing_sampler_profiler_unittest.cc
@@ -8,25 +8,18 @@
#include "base/at_exit.h"
#include "base/bind.h"
-#include "base/bind_helpers.h"
#include "base/json/json_reader.h"
-#include "base/memory/ref_counted_memory.h"
#include "base/run_loop.h"
-#include "base/test/bind_test_util.h"
#include "base/test/task_environment.h"
#include "base/threading/thread.h"
-#include "base/time/time.h"
#include "base/trace_event/trace_buffer.h"
#include "base/trace_event/trace_event.h"
#include "build/build_config.h"
#include "services/tracing/public/cpp/buildflags.h"
-#include "services/tracing/public/cpp/perfetto/producer_client.h"
+#include "services/tracing/public/cpp/perfetto/producer_test_utils.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/perfetto/include/perfetto/ext/base/utils.h"
-#include "third_party/perfetto/include/perfetto/protozero/scattered_stream_null_delegate.h"
#include "third_party/perfetto/protos/perfetto/trace/trace_packet.pb.h"
-#include "third_party/perfetto/protos/perfetto/trace/trace_packet.pbzero.h"
#if BUILDFLAG(ENABLE_LOADER_LOCK_SAMPLING)
#include "base/test/trace_event_analyzer.h"
@@ -40,111 +33,6 @@ using base::trace_event::TraceLog;
using ::testing::Invoke;
using ::testing::Return;
-class MockTraceWriter : public perfetto::TraceWriter {
- public:
- MockTraceWriter(
- const base::RepeatingCallback<void(
- std::unique_ptr<perfetto::protos::TracePacket>)>& on_packet_callback)
- : delegate_(perfetto::base::kPageSize),
- stream_(&delegate_),
- on_packet_callback_(std::move(on_packet_callback)) {
- trace_packet_.Reset(&stream_);
- }
-
- 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));
- on_packet_callback_.Run(std::move(proto));
- }
-
- stream_.Reset(buffer);
- trace_packet_.Reset(&stream_);
- }
-
- perfetto::TraceWriter::TracePacketHandle NewTracePacket() override {
- FlushPacketIfPossible();
-
- 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_;
-
- base::RepeatingCallback<void(std::unique_ptr<perfetto::protos::TracePacket>)>
- on_packet_callback_;
-
- DISALLOW_COPY_AND_ASSIGN(MockTraceWriter);
-};
-
-class MockPerfettoProducer : public ProducerClient {
- public:
- explicit MockPerfettoProducer(std::unique_ptr<PerfettoTaskRunner> task_runner)
- : ProducerClient(task_runner.get()),
- task_runner_(std::move(task_runner)) {}
-
- std::unique_ptr<perfetto::TraceWriter> CreateTraceWriter(
- perfetto::BufferID target_buffer,
- perfetto::BufferExhaustedPolicy =
- perfetto::BufferExhaustedPolicy::kDefault) override {
- auto packet_callback = base::BindRepeating(
- [](base::WeakPtr<MockPerfettoProducer> weak_self,
- scoped_refptr<base::SequencedTaskRunner> task_runner,
- std::unique_ptr<perfetto::protos::TracePacket> packet) {
- task_runner->PostTask(
- FROM_HERE, base::BindOnce(&MockPerfettoProducer::ReceivePacket,
- weak_self, std::move(packet)));
- },
- weak_ptr_factory_.GetWeakPtr(), base::SequencedTaskRunnerHandle::Get());
-
- return std::make_unique<MockTraceWriter>(packet_callback);
- }
-
- void ReceivePacket(std::unique_ptr<perfetto::protos::TracePacket> packet) {
- base::AutoLock lock(lock_);
- finalized_packets_.push_back(std::move(packet));
- }
-
- const perfetto::protos::TracePacket* GetFinalizedPacket(
- size_t packet_index = 0) {
- base::AutoLock lock(lock_);
- EXPECT_GT(finalized_packets_.size(), packet_index);
- return finalized_packets_[packet_index].get();
- }
-
- const std::vector<std::unique_ptr<perfetto::protos::TracePacket>>&
- finalized_packets() const {
- return finalized_packets_;
- }
-
- private:
- base::Lock lock_; // protects finalized_packets_
- std::vector<std::unique_ptr<perfetto::protos::TracePacket>>
- finalized_packets_;
-
- std::unique_ptr<PerfettoTaskRunner> task_runner_;
- base::WeakPtrFactory<MockPerfettoProducer> weak_ptr_factory_{this};
- DISALLOW_COPY_AND_ASSIGN(MockPerfettoProducer);
-};
-
#if BUILDFLAG(ENABLE_LOADER_LOCK_SAMPLING)
class MockLoaderLockSampler : public TracingSamplerProfiler::LoaderLockSampler {
@@ -189,7 +77,8 @@ class TracingSampleProfilerTest : public testing::Test {
task_environment_.GetMainThreadTaskRunner());
producer_ =
- std::make_unique<MockPerfettoProducer>(std::move(perfetto_wrapper));
+ std::make_unique<TestProducerClient>(std::move(perfetto_wrapper),
+ /*log_only_main_thread=*/false);
#if BUILDFLAG(ENABLE_LOADER_LOCK_SAMPLING)
ON_CALL(mock_loader_lock_sampler_, IsLoaderLockHeld())
@@ -249,7 +138,7 @@ class TracingSampleProfilerTest : public testing::Test {
return profile_sequence_id;
}
- const MockPerfettoProducer* producer() const { return producer_.get(); }
+ const TestProducerClient* producer() const { return producer_.get(); }
protected:
base::test::TaskEnvironment task_environment_;
@@ -258,7 +147,7 @@ class TracingSampleProfilerTest : public testing::Test {
base::ShadowingAtExitManager at_exit_manager_;
base::trace_event::TraceResultBuffer trace_buffer_;
- std::unique_ptr<MockPerfettoProducer> producer_;
+ std::unique_ptr<TestProducerClient> producer_;
// Number of stack sampling events received.
size_t events_stack_received_count_ = 0;
@@ -501,50 +390,70 @@ TEST_F(TracingSampleProfilerTest, SampleLoaderLockWithoutMock) {
#endif // BUILDFLAG(ENABLE_LOADER_LOCK_SAMPLING)
-TEST(TracingProfileBuilderTest, ValidModule) {
+class TracingProfileBuilderTest : public testing::Test {
+ public:
+ void SetUp() override {
+ auto perfetto_wrapper = std::make_unique<PerfettoTaskRunner>(
+ task_environment_.GetMainThreadTaskRunner());
+ producer_client_ = std::make_unique<TestProducerClient>(
+ std::move(perfetto_wrapper), /*log_only_main_thread=*/false);
+ }
+
+ void TearDown() override { producer_client_.reset(); }
+
+ TestProducerClient* producer() { return producer_client_.get(); }
+
+ private:
+ // Should be the first member.
+ base::test::TaskEnvironment task_environment_;
+
+ std::unique_ptr<TestProducerClient> producer_client_;
+};
+
+TEST_F(TracingProfileBuilderTest, ValidModule) {
TestModule module;
TracingSamplerProfiler::TracingProfileBuilder profile_builder(
- base::PlatformThreadId(),
- std::make_unique<MockTraceWriter>(base::DoNothing()), false);
+ base::PlatformThreadId(), std::make_unique<TestTraceWriter>(producer()),
+ false);
profile_builder.OnSampleCompleted({base::Frame(0x1010, &module)},
base::TimeTicks());
}
-TEST(TracingProfileBuilderTest, InvalidModule) {
+TEST_F(TracingProfileBuilderTest, InvalidModule) {
TracingSamplerProfiler::TracingProfileBuilder profile_builder(
- base::PlatformThreadId(),
- std::make_unique<MockTraceWriter>(base::DoNothing()), false);
+ base::PlatformThreadId(), std::make_unique<TestTraceWriter>(producer()),
+ false);
profile_builder.OnSampleCompleted({base::Frame(0x1010, nullptr)},
base::TimeTicks());
}
#if defined(OS_ANDROID) || defined(OS_LINUX)
-TEST(TracingProfileBuilderTest, MangleELFModuleID) {
+TEST_F(TracingProfileBuilderTest, MangleELFModuleID) {
TestModule module;
// See explanation for the module_id mangling in
// TracingSamplerProfiler::TracingProfileBuilder::GetCallstackIDAndMaybeEmit.
module.set_id("7F0715C286F8B16C10E4AD349CDA3B9B56C7A773");
- bool found_build_id = false;
- auto on_packet_callback = base::BindLambdaForTesting(
- [&found_build_id](std::unique_ptr<perfetto::protos::TracePacket> packet) {
- if (!packet->has_interned_data() ||
- packet->interned_data().build_ids_size() == 0) {
- return;
- }
-
- found_build_id = true;
- EXPECT_EQ(packet->interned_data().build_ids(0).str(),
- "C215077FF8866CB110E4AD349CDA3B9B0");
- });
-
- auto trace_writer = std::make_unique<MockTraceWriter>(on_packet_callback);
- auto* raw_trace_writer = trace_writer.get();
TracingSamplerProfiler::TracingProfileBuilder profile_builder(
- base::PlatformThreadId(), std::move(trace_writer), false);
+ base::PlatformThreadId(), std::make_unique<TestTraceWriter>(producer()),
+ false);
profile_builder.OnSampleCompleted({base::Frame(0x1010, &module)},
base::TimeTicks());
- raw_trace_writer->FlushPacketIfPossible();
+ producer()->FlushPacketIfPossible();
+
+ bool found_build_id = false;
+ for (unsigned i = 0; i < producer()->GetFinalizedPacketCount(); ++i) {
+ const perfetto::protos::TracePacket* packet =
+ producer()->GetFinalizedPacket(i);
+ if (!packet->has_interned_data() ||
+ packet->interned_data().build_ids_size() == 0) {
+ return;
+ }
+
+ found_build_id = true;
+ EXPECT_EQ(packet->interned_data().build_ids(0).str(),
+ "C215077FF8866CB110E4AD349CDA3B9B0");
+ }
EXPECT_TRUE(found_build_id);
}
#endif
diff --git a/chromium/services/tracing/public/cpp/trace_event_agent.cc b/chromium/services/tracing/public/cpp/trace_event_agent.cc
index 6427c8b5ccd..bd7ed5c242d 100644
--- a/chromium/services/tracing/public/cpp/trace_event_agent.cc
+++ b/chromium/services/tracing/public/cpp/trace_event_agent.cc
@@ -21,9 +21,13 @@
#include "services/tracing/public/cpp/perfetto/perfetto_traced_process.h"
#include "services/tracing/public/cpp/perfetto/trace_event_data_source.h"
#include "services/tracing/public/cpp/stack_sampling/tracing_sampler_profiler.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/tracing_features.h"
+#if defined(OS_ANDROID)
+#include "services/tracing/public/cpp/stack_sampling/reached_code_data_source_android.h"
+#endif
+
namespace tracing {
// static
@@ -41,14 +45,17 @@ TraceEventAgent::TraceEventAgent() {
->GetArgumentFilterPredicate()
.is_null()) {
base::trace_event::TraceLog::GetInstance()->SetArgumentFilterPredicate(
- base::BindRepeating(&IsTraceEventArgsWhitelisted));
+ base::BindRepeating(&IsTraceEventArgsAllowlisted));
base::trace_event::TraceLog::GetInstance()->SetMetadataFilterPredicate(
- base::BindRepeating(&IsMetadataWhitelisted));
+ base::BindRepeating(&IsMetadataAllowlisted));
}
PerfettoTracedProcess::Get()->AddDataSource(
TraceEventDataSource::GetInstance());
TracingSamplerProfiler::RegisterDataSource();
+#if defined(OS_ANDROID)
+ PerfettoTracedProcess::Get()->AddDataSource(ReachedCodeDataSource::Get());
+#endif
}
TraceEventAgent::~TraceEventAgent() = default;
diff --git a/chromium/services/tracing/public/cpp/trace_event_args_whitelist.cc b/chromium/services/tracing/public/cpp/trace_event_args_allowlist.cc
index 7e5af23624b..23be6e65ff1 100644
--- a/chromium/services/tracing/public/cpp/trace_event_args_whitelist.cc
+++ b/chromium/services/tracing/public/cpp/trace_event_args_allowlist.cc
@@ -2,7 +2,7 @@
// 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/trace_event_args_whitelist.h"
+#include "services/tracing/public/cpp/trace_event_args_allowlist.h"
#include "base/bind.h"
#include "base/strings/pattern.h"
@@ -13,14 +13,14 @@
namespace tracing {
namespace {
-// Each whitelist entry is used to whitelist an array arguments for a
+// Each allowlist entry is used to allowlist an array arguments for a
// single or group of trace events.
-struct WhitelistEntry {
+struct AllowlistEntry {
// Category name of the interested trace event.
const char* category_name;
// Pattern to match the interested trace event name.
const char* event_name;
- // List of patterns that match the whitelisted arguments.
+ // List of patterns that match the allowlisted arguments.
const char* const* arg_name_filter;
};
@@ -38,15 +38,17 @@ const char* const kMemoryDumpAllowedArgs[] = {
const char* const kRendererHostAllowedArgs[] = {
"class", "line", "should_background", "has_pending_views",
"bytes_allocated", nullptr};
+const char* const kUIAllowedArgs[] = {"dpi", "message_id", nullptr};
const char* const kV8GCAllowedArgs[] = {"num_items", "num_tasks", nullptr};
const char* const kTopLevelFlowAllowedArgs[] = {"task_queue_name", nullptr};
const char* const kTopLevelIpcRunTaskAllowedArgs[] = {"ipc_hash", nullptr};
const char* const kLifecyclesTaskPostedAllowedArgs[] = {
"task_queue_name", "time_since_disabled_ms", "ipc_hash", "location",
nullptr};
-const char* const kMemoryPressureEventsAllowedArgs[] = {"level", nullptr};
+const char* const kMemoryPressureEventsAllowedArgs[] = {
+ "level", "listener_creation_info", nullptr};
-const WhitelistEntry kEventArgsWhitelist[] = {
+const AllowlistEntry kEventArgsAllowlist[] = {
{"__metadata", "thread_name", nullptr},
{"__metadata", "process_name", nullptr},
{"__metadata", "process_uptime_seconds", nullptr},
@@ -54,6 +56,8 @@ const WhitelistEntry kEventArgsWhitelist[] = {
{"__metadata", "chrome_library_module", nullptr},
{"__metadata", "stackFrames", nullptr},
{"__metadata", "typeNames", nullptr},
+ {"base", "MemoryPressureListener::Notify",
+ kMemoryPressureEventsAllowedArgs},
{"base", "MessagePumpForUI::ProcessNextWindowsMessage PeekMessage",
kPeekMessageAllowedArgs},
{"base", "MultiSourceMemoryPressureMonitor::OnMemoryPressureLevelChanged",
@@ -65,7 +69,7 @@ const WhitelistEntry kEventArgsWhitelist[] = {
{"base", "ScopedBlockingCall*", kScopedBlockingCallAllowedArgs},
{"base", "ScopedMayLoadLibraryAtBackgroundPriority",
kScopedBlockingCallAllowedArgs},
- {"benchmark", "TestWhitelist*", nullptr},
+ {"benchmark", "TestAllowlist*", nullptr},
{"blink", "MemoryPressureListenerRegistry::onMemoryPressure",
kMemoryPressureEventsAllowedArgs},
{"browser", "KeyedServiceFactory::GetServiceForContext", nullptr},
@@ -92,17 +96,18 @@ const WhitelistEntry kEventArgsWhitelist[] = {
{TRACE_DISABLED_BY_DEFAULT("memory-infra"), "*", kMemoryDumpAllowedArgs},
{TRACE_DISABLED_BY_DEFAULT("system_stats"), "*", nullptr},
{TRACE_DISABLED_BY_DEFAULT("v8.gc"), "*", kV8GCAllowedArgs},
+ {"ui", "HWNDMessageHandler::OnWndProc", kUIAllowedArgs},
+ {"ui", "HWNDMessageHandler::OnDwmCompositionChanged", kUIAllowedArgs},
{"ui", "RenderTextHarfBuzz::FallbackFont", kFallbackFontAllowedArgs},
{"ui", "RenderTextHarfBuzz::GetFallbackFonts",
kGetFallbackFontsAllowedArgs},
{TRACE_DISABLED_BY_DEFAULT("user_action_samples"), "UserAction", nullptr},
- {TRACE_DISABLED_BY_DEFAULT("toplevel.flow"), "SequenceManager::PostTask",
- kTopLevelFlowAllowedArgs},
+ {"toplevel.flow", "SequenceManager::PostTask", kTopLevelFlowAllowedArgs},
{TRACE_DISABLED_BY_DEFAULT("lifecycles"), "task_posted_to_disabled_queue",
kLifecyclesTaskPostedAllowedArgs},
{nullptr, nullptr, nullptr}};
-const char* kMetadataWhitelist[] = {"chrome-bitness",
+const char* kMetadataAllowlist[] = {"chrome-bitness",
"chrome-library-name",
"clock-domain",
"config",
@@ -124,7 +129,7 @@ const char* kMetadataWhitelist[] = {"chrome-bitness",
} // namespace
-bool IsTraceArgumentNameWhitelisted(const char* const* granular_filter,
+bool IsTraceArgumentNameAllowlisted(const char* const* granular_filter,
const char* arg_name) {
for (int i = 0; granular_filter[i] != nullptr; ++i) {
if (base::MatchPattern(arg_name, granular_filter[i]))
@@ -134,7 +139,7 @@ bool IsTraceArgumentNameWhitelisted(const char* const* granular_filter,
return false;
}
-bool IsTraceEventArgsWhitelisted(
+bool IsTraceEventArgsAllowlisted(
const char* category_group_name,
const char* event_name,
base::trace_event::ArgumentNameFilterPredicate* arg_name_filter) {
@@ -144,16 +149,16 @@ bool IsTraceEventArgsWhitelisted(
",");
while (category_group_tokens.GetNext()) {
const std::string& category_group_token = category_group_tokens.token();
- for (int i = 0; kEventArgsWhitelist[i].category_name != nullptr; ++i) {
- const WhitelistEntry& whitelist_entry = kEventArgsWhitelist[i];
- DCHECK(whitelist_entry.event_name);
+ for (int i = 0; kEventArgsAllowlist[i].category_name != nullptr; ++i) {
+ const AllowlistEntry& allowlist_entry = kEventArgsAllowlist[i];
+ DCHECK(allowlist_entry.event_name);
if (base::MatchPattern(category_group_token,
- whitelist_entry.category_name) &&
- base::MatchPattern(event_name, whitelist_entry.event_name)) {
- if (whitelist_entry.arg_name_filter) {
+ allowlist_entry.category_name) &&
+ base::MatchPattern(event_name, allowlist_entry.event_name)) {
+ if (allowlist_entry.arg_name_filter) {
*arg_name_filter = base::BindRepeating(
- &IsTraceArgumentNameWhitelisted, whitelist_entry.arg_name_filter);
+ &IsTraceArgumentNameAllowlisted, allowlist_entry.arg_name_filter);
}
return true;
}
@@ -163,9 +168,9 @@ bool IsTraceEventArgsWhitelisted(
return false;
}
-bool IsMetadataWhitelisted(const std::string& metadata_name) {
- for (size_t i = 0; kMetadataWhitelist[i] != nullptr; ++i) {
- if (base::MatchPattern(metadata_name, kMetadataWhitelist[i])) {
+bool IsMetadataAllowlisted(const std::string& metadata_name) {
+ for (size_t i = 0; kMetadataAllowlist[i] != nullptr; ++i) {
+ if (base::MatchPattern(metadata_name, kMetadataAllowlist[i])) {
return true;
}
}
diff --git a/chromium/services/tracing/public/cpp/trace_event_args_whitelist.h b/chromium/services/tracing/public/cpp/trace_event_args_allowlist.h
index e3a19458ba6..c1eb42f4888 100644
--- a/chromium/services/tracing/public/cpp/trace_event_args_whitelist.h
+++ b/chromium/services/tracing/public/cpp/trace_event_args_allowlist.h
@@ -2,8 +2,8 @@
// 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_TRACE_EVENT_ARGS_WHITELIST_H_
-#define SERVICES_TRACING_PUBLIC_CPP_TRACE_EVENT_ARGS_WHITELIST_H_
+#ifndef SERVICES_TRACING_PUBLIC_CPP_TRACE_EVENT_ARGS_ALLOWLIST_H_
+#define SERVICES_TRACING_PUBLIC_CPP_TRACE_EVENT_ARGS_ALLOWLIST_H_
#include <string>
@@ -15,18 +15,18 @@ namespace tracing {
// TODO(ssid): This is a temporary argument filter that will be removed once
// slow reports moves to using proto completely.
-// Used to filter trace event arguments against a whitelist of events that
+// Used to filter trace event arguments against a allowlist of events that
// have been manually vetted to not include any PII.
-bool COMPONENT_EXPORT(TRACING_CPP) IsTraceEventArgsWhitelisted(
+bool COMPONENT_EXPORT(TRACING_CPP) IsTraceEventArgsAllowlisted(
const char* category_group_name,
const char* event_name,
base::trace_event::ArgumentNameFilterPredicate* arg_name_filter);
-// Used to filter metadata against a whitelist of metadata names that have been
+// Used to filter metadata against a allowlist of metadata names that have been
// manually vetted to not include any PII.
bool COMPONENT_EXPORT(TRACING_CPP)
- IsMetadataWhitelisted(const std::string& metadata_name);
+ IsMetadataAllowlisted(const std::string& metadata_name);
} // namespace tracing
-#endif // SERVICES_TRACING_PUBLIC_CPP_TRACE_EVENT_ARGS_WHITELIST_H_
+#endif // SERVICES_TRACING_PUBLIC_CPP_TRACE_EVENT_ARGS_ALLOWLIST_H_
diff --git a/chromium/services/tracing/public/cpp/trace_startup.cc b/chromium/services/tracing/public/cpp/trace_startup.cc
index 106002df61f..188d127cd43 100644
--- a/chromium/services/tracing/public/cpp/trace_startup.cc
+++ b/chromium/services/tracing/public/cpp/trace_startup.cc
@@ -15,7 +15,7 @@
#include "services/tracing/public/cpp/perfetto/system_producer.h"
#include "services/tracing/public/cpp/perfetto/trace_event_data_source.h"
#include "services/tracing/public/cpp/trace_event_agent.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/tracing_features.h"
#include "third_party/perfetto/include/perfetto/tracing/track.h"
diff --git a/chromium/services/tracing/public/mojom/perfetto_service.mojom b/chromium/services/tracing/public/mojom/perfetto_service.mojom
index 170d6f26c1e..7af80cb0a1a 100644
--- a/chromium/services/tracing/public/mojom/perfetto_service.mojom
+++ b/chromium/services/tracing/public/mojom/perfetto_service.mojom
@@ -17,6 +17,8 @@ const string kSystemTraceDataSourceName = "org.chromium.trace_system";
const string kArcTraceDataSourceName = "org.chromium.trace_arc";
const string kSamplerProfilerSourceName = "org.chromium.sampler_profiler";
const string kJavaHeapProfilerSourceName = "org.chromium.java_heap_profiler";
+const string kReachedCodeProfilerSourceName =
+ "org.chromium.reached_code_profiler";
// Brief description of the flow: There's a per-process ProducerClient which
// connects to the central PerfettoService and establishes a two-way connection