diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-10-12 14:27:29 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-10-13 09:35:20 +0000 |
commit | c30a6232df03e1efbd9f3b226777b07e087a1122 (patch) | |
tree | e992f45784689f373bcc38d1b79a239ebe17ee23 /chromium/services/tracing | |
parent | 7b5b123ac58f58ffde0f4f6e488bcd09aa4decd3 (diff) | |
download | qtwebengine-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')
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 |