summaryrefslogtreecommitdiff
path: root/chromium/components/metrics
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2018-08-28 15:28:34 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2018-08-28 13:54:51 +0000
commit2a19c63448c84c1805fb1a585c3651318bb86ca7 (patch)
treeeb17888e8531aa6ee5e85721bd553b832a7e5156 /chromium/components/metrics
parentb014812705fc80bff0a5c120dfcef88f349816dc (diff)
downloadqtwebengine-chromium-2a19c63448c84c1805fb1a585c3651318bb86ca7.tar.gz
BASELINE: Update Chromium to 69.0.3497.70
Change-Id: I2b7b56e4e7a8b26656930def0d4575dc32b900a0 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/components/metrics')
-rw-r--r--chromium/components/metrics/BUILD.gn10
-rw-r--r--chromium/components/metrics/call_stack_profile_builder.cc106
-rw-r--r--chromium/components/metrics/call_stack_profile_builder.h77
-rw-r--r--chromium/components/metrics/call_stack_profile_builder_unittest.cc159
-rw-r--r--chromium/components/metrics/call_stack_profile_collector.cc12
-rw-r--r--chromium/components/metrics/call_stack_profile_collector.h2
-rw-r--r--chromium/components/metrics/call_stack_profile_metrics_provider.cc138
-rw-r--r--chromium/components/metrics/call_stack_profile_metrics_provider.h23
-rw-r--r--chromium/components/metrics/call_stack_profile_metrics_provider_unittest.cc521
-rw-r--r--chromium/components/metrics/child_call_stack_profile_collector.cc34
-rw-r--r--chromium/components/metrics/child_call_stack_profile_collector.h48
-rw-r--r--chromium/components/metrics/child_call_stack_profile_collector_unittest.cc85
-rw-r--r--chromium/components/metrics/generate_expired_histograms_array.gni2
-rw-r--r--chromium/components/metrics/gpu/gpu_metrics_provider.cc9
-rw-r--r--chromium/components/metrics/metrics_log.cc5
-rw-r--r--chromium/components/metrics/metrics_log_unittest.cc6
-rw-r--r--chromium/components/metrics/metrics_state_manager_unittest.cc2
-rw-r--r--chromium/components/metrics/net/net_metrics_log_uploader.cc7
-rw-r--r--chromium/components/metrics/net/net_metrics_log_uploader_unittest.cc16
-rw-r--r--chromium/components/metrics/net/network_metrics_provider.cc4
-rw-r--r--chromium/components/metrics/net/network_metrics_provider.h2
-rw-r--r--chromium/components/metrics/public/cpp/OWNERS2
-rw-r--r--chromium/components/metrics/public/cpp/call_stack_profile.typemap2
-rw-r--r--chromium/components/metrics/public/cpp/call_stack_profile_struct_traits.h16
-rw-r--r--chromium/components/metrics/public/cpp/call_stack_profile_struct_traits_unittest.cc134
-rw-r--r--chromium/components/metrics/public/interfaces/call_stack_profile_collector.mojom2
-rw-r--r--chromium/components/metrics/single_sample_metrics_factory_impl_unittest.cc2
-rw-r--r--chromium/components/metrics/stability_metrics_helper.cc18
-rw-r--r--chromium/components/metrics/stability_metrics_helper.h7
-rw-r--r--chromium/components/metrics/stability_metrics_helper_unittest.cc2
-rw-r--r--chromium/components/metrics/stability_metrics_provider_unittest.cc2
31 files changed, 814 insertions, 641 deletions
diff --git a/chromium/components/metrics/BUILD.gn b/chromium/components/metrics/BUILD.gn
index 75d36a28d49..15b3a14d569 100644
--- a/chromium/components/metrics/BUILD.gn
+++ b/chromium/components/metrics/BUILD.gn
@@ -105,7 +105,7 @@ static_library("metrics") {
]
public_deps = [
- ":call_stack_profile_params",
+ ":call_stack_profile",
"//third_party/metrics_proto",
]
@@ -256,8 +256,10 @@ static_library("single_sample_metrics") {
]
}
-source_set("call_stack_profile_params") {
+source_set("call_stack_profile") {
sources = [
+ "call_stack_profile_builder.cc",
+ "call_stack_profile_builder.h",
"call_stack_profile_params.h",
]
@@ -283,6 +285,7 @@ source_set("child_call_stacks") {
"child_call_stack_profile_collector.h",
]
deps = [
+ ":call_stack_profile",
"//components/metrics/public/interfaces:call_stack_mojo_bindings",
"//services/service_manager/public/cpp",
]
@@ -326,6 +329,7 @@ if (is_linux) {
source_set("unit_tests") {
testonly = true
sources = [
+ "call_stack_profile_builder_unittest.cc",
"call_stack_profile_metrics_provider_unittest.cc",
"child_call_stack_profile_collector_unittest.cc",
"cloned_install_detector_unittest.cc",
@@ -357,7 +361,7 @@ source_set("unit_tests") {
]
deps = [
- ":call_stack_profile_params",
+ ":call_stack_profile",
":child_call_stacks",
":component_metrics",
":metrics",
diff --git a/chromium/components/metrics/call_stack_profile_builder.cc b/chromium/components/metrics/call_stack_profile_builder.cc
new file mode 100644
index 00000000000..f308c93da51
--- /dev/null
+++ b/chromium/components/metrics/call_stack_profile_builder.cc
@@ -0,0 +1,106 @@
+// Copyright 2018 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 "components/metrics/call_stack_profile_builder.h"
+
+#include <utility>
+
+#include "base/atomicops.h"
+#include "base/logging.h"
+
+using StackSamplingProfiler = base::StackSamplingProfiler;
+
+namespace metrics {
+
+namespace {
+
+// This global variables holds the current system state and is recorded with
+// every captured sample, done on a separate thread which is why updates to
+// this must be atomic. A PostTask to move the the updates to that thread
+// would skew the timing and a lock could result in deadlock if the thread
+// making a change was also being profiled and got stopped.
+static base::subtle::Atomic32 g_process_milestones = 0;
+
+void ChangeAtomicFlags(base::subtle::Atomic32* flags,
+ base::subtle::Atomic32 set,
+ base::subtle::Atomic32 clear) {
+ DCHECK(set != 0 || clear != 0);
+ DCHECK_EQ(0, set & clear);
+
+ base::subtle::Atomic32 bits = base::subtle::NoBarrier_Load(flags);
+ while (true) {
+ base::subtle::Atomic32 existing = base::subtle::NoBarrier_CompareAndSwap(
+ flags, bits, (bits | set) & ~clear);
+ if (existing == bits)
+ break;
+ bits = existing;
+ }
+}
+
+} // namespace
+
+CallStackProfileBuilder::CallStackProfileBuilder(
+ const CompletedCallback& callback)
+ : callback_(callback) {}
+
+CallStackProfileBuilder::~CallStackProfileBuilder() = default;
+
+void CallStackProfileBuilder::RecordAnnotations() {
+ // The code inside this method must not do anything that could acquire a
+ // mutex, including allocating memory (which includes LOG messages) because
+ // that mutex could be held by a stopped thread, thus resulting in deadlock.
+ sample_.process_milestones =
+ base::subtle::NoBarrier_Load(&g_process_milestones);
+}
+
+void CallStackProfileBuilder::OnSampleCompleted(
+ std::vector<StackSamplingProfiler::InternalFrame> internal_frames) {
+ DCHECK(sample_.frames.empty());
+
+ // Dedup modules and convert InternalFrames to Frames.
+ for (const auto& internal_frame : internal_frames) {
+ const StackSamplingProfiler::InternalModule& module(
+ internal_frame.internal_module);
+ if (!module.is_valid) {
+ sample_.frames.emplace_back(internal_frame.instruction_pointer,
+ base::kUnknownModuleIndex);
+ continue;
+ }
+
+ auto loc = module_index_.find(module.base_address);
+ if (loc == module_index_.end()) {
+ profile_.modules.emplace_back(module.base_address, module.id,
+ module.filename);
+ size_t index = profile_.modules.size() - 1;
+ loc = module_index_.insert(std::make_pair(module.base_address, index))
+ .first;
+ }
+ sample_.frames.emplace_back(internal_frame.instruction_pointer,
+ loc->second);
+ }
+
+ profile_.samples.push_back(std::move(sample_));
+ sample_ = StackSamplingProfiler::Sample();
+}
+
+void CallStackProfileBuilder::OnProfileCompleted(
+ base::TimeDelta profile_duration,
+ base::TimeDelta sampling_period) {
+ profile_.profile_duration = profile_duration;
+ profile_.sampling_period = sampling_period;
+
+ // Run the associated callback, passing the collected profile.
+ callback_.Run(std::move(profile_));
+}
+
+// static
+void CallStackProfileBuilder::SetProcessMilestone(int milestone) {
+ DCHECK_LE(0, milestone);
+ DCHECK_GT(static_cast<int>(sizeof(g_process_milestones) * 8), milestone);
+ DCHECK_EQ(0, base::subtle::NoBarrier_Load(&g_process_milestones) &
+ (1 << milestone));
+ ChangeAtomicFlags(&g_process_milestones, 1 << milestone, 0);
+}
+
+} // namespace metrics
diff --git a/chromium/components/metrics/call_stack_profile_builder.h b/chromium/components/metrics/call_stack_profile_builder.h
new file mode 100644
index 00000000000..ec01592686b
--- /dev/null
+++ b/chromium/components/metrics/call_stack_profile_builder.h
@@ -0,0 +1,77 @@
+// Copyright 2018 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 COMPONENTS_METRICS_CALL_STACK_PROFILE_BUILDER_H_
+#define COMPONENTS_METRICS_CALL_STACK_PROFILE_BUILDER_H_
+
+#include "base/profiler/stack_sampling_profiler.h"
+
+#include <map>
+
+#include "base/callback.h"
+
+namespace metrics {
+
+// CallStackProfileBuilder builds a CallStackProfile from the collected sampling
+// data.
+//
+// The results of the profile building -- a CallStackProfile, is passed to the
+// completed callback. A CallStackProfile contains a set of Samples and
+// Modules, and other sampling information. One Sample corresponds to a single
+// recorded stack, and the Modules record those modules associated with the
+// recorded stack frames.
+class CallStackProfileBuilder
+ : public base::StackSamplingProfiler::ProfileBuilder {
+ public:
+ // The callback type used to collect a completed profile. The passed
+ // CallStackProfile is move-only. Other threads, including the UI thread, may
+ // block on callback completion so this should run as quickly as possible.
+ //
+ // IMPORTANT NOTE: The callback is invoked on a thread the profiler
+ // constructs, rather than on the thread used to construct the profiler, and
+ // thus the callback must be callable on any thread. For threads with message
+ // loops that create CallStackProfileBuilders, posting a task to the message
+ // loop with the moved (i.e. std::move) profile is the thread-safe callback
+ // implementation.
+ using CompletedCallback =
+ base::Callback<void(base::StackSamplingProfiler::CallStackProfile)>;
+
+ CallStackProfileBuilder(const CompletedCallback& callback);
+
+ ~CallStackProfileBuilder() override;
+
+ // base::StackSamplingProfiler::ProfileBuilder:
+ void RecordAnnotations() override;
+ void OnSampleCompleted(std::vector<base::StackSamplingProfiler::InternalFrame>
+ internal_frames) override;
+ void OnProfileCompleted(base::TimeDelta profile_duration,
+ base::TimeDelta sampling_period) override;
+
+ // Sets the current system state that is recorded with each captured stack
+ // frame. This is thread-safe so can be called from anywhere. The parameter
+ // value should be from an enumeration of the appropriate type with values
+ // ranging from 0 to 31, inclusive. This sets bits within Sample field of
+ // |process_milestones|. The actual meanings of these bits are defined
+ // (globally) by the caller(s).
+ static void SetProcessMilestone(int milestone);
+
+ private:
+ // The collected stack samples.
+ base::StackSamplingProfiler::CallStackProfile profile_;
+
+ // The current sample being recorded.
+ base::StackSamplingProfiler::Sample sample_;
+
+ // The indexes of internal modules, indexed by module's base_address.
+ std::map<uintptr_t, size_t> module_index_;
+
+ // Callback made when sampling a profile completes.
+ const CompletedCallback callback_;
+
+ DISALLOW_COPY_AND_ASSIGN(CallStackProfileBuilder);
+};
+
+} // namespace metrics
+
+#endif // COMPONENTS_METRICS_CALL_STACK_PROFILE_BUILDER_H_
diff --git a/chromium/components/metrics/call_stack_profile_builder_unittest.cc b/chromium/components/metrics/call_stack_profile_builder_unittest.cc
new file mode 100644
index 00000000000..93ff7cccca9
--- /dev/null
+++ b/chromium/components/metrics/call_stack_profile_builder_unittest.cc
@@ -0,0 +1,159 @@
+// Copyright 2018 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 "components/metrics/call_stack_profile_builder.h"
+
+#include "base/files/file_path.h"
+#include "base/test/bind_test_util.h"
+#include "base/time/time.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using StackSamplingProfiler = base::StackSamplingProfiler;
+using InternalFrame = StackSamplingProfiler::InternalFrame;
+using InternalModule = StackSamplingProfiler::InternalModule;
+using CallStackProfile = StackSamplingProfiler::CallStackProfile;
+
+namespace metrics {
+
+namespace {
+
+// Called on the profiler thread when complete, to collect profile.
+void SaveProfile(CallStackProfile* profile, CallStackProfile pending_profile) {
+ *profile = std::move(pending_profile);
+}
+
+} // namespace
+
+TEST(CallStackProfileBuilderTest, SetProcessMilestone) {
+ CallStackProfile profile;
+
+ // Set up a callback to record the CallStackProfile to local variable
+ // |profile|.
+ auto profile_builder = std::make_unique<CallStackProfileBuilder>(
+ Bind(&SaveProfile, Unretained(&profile)));
+
+ profile_builder->RecordAnnotations();
+ profile_builder->OnSampleCompleted(std::vector<InternalFrame>());
+
+ CallStackProfileBuilder::SetProcessMilestone(1);
+ profile_builder->RecordAnnotations();
+ profile_builder->OnSampleCompleted(std::vector<InternalFrame>());
+
+ profile_builder->OnProfileCompleted(base::TimeDelta(), base::TimeDelta());
+
+ ASSERT_EQ(2u, profile.samples.size());
+ EXPECT_EQ(0u, profile.samples[0].process_milestones);
+ EXPECT_EQ(1u << 1, profile.samples[1].process_milestones);
+}
+
+TEST(CallStackProfileBuilderTest, OnSampleCompleted) {
+ CallStackProfile profile;
+
+ // Set up a callback to record the CallStackProfile to local variable
+ // |profile|.
+ auto profile_builder = std::make_unique<CallStackProfileBuilder>(
+ Bind(&SaveProfile, Unretained(&profile)));
+
+ InternalModule module1 = {0xccccdddd, "1",
+ base::FilePath(FILE_PATH_LITERAL("file_path_1"))};
+ InternalModule module2 = {0xccddccdd, "2",
+ base::FilePath(FILE_PATH_LITERAL("file_path_2"))};
+ InternalFrame frame1 = {0xaaaabbbb, module1};
+ InternalFrame frame2 = {0xaabbaabb, module2};
+
+ std::vector<InternalFrame> frames = {frame1, frame2};
+
+ profile_builder->OnSampleCompleted(frames);
+ profile_builder->OnProfileCompleted(base::TimeDelta(), base::TimeDelta());
+
+ ASSERT_EQ(1u, profile.samples.size());
+ ASSERT_EQ(2u, profile.samples[0].frames.size());
+ EXPECT_EQ(0u, profile.samples[0].frames[0].module_index);
+ EXPECT_EQ(1u, profile.samples[0].frames[1].module_index);
+}
+
+TEST(CallStackProfileBuilderTest, OnProfileCompleted) {
+ CallStackProfile profile;
+
+ // Set up a callback to record the CallStackProfile to local variable
+ // |profile|.
+ auto profile_builder = std::make_unique<CallStackProfileBuilder>(
+ Bind(&SaveProfile, Unretained(&profile)));
+
+ InternalModule module1 = {0xccccdddd, "1",
+ base::FilePath(FILE_PATH_LITERAL("file_path_1"))};
+ InternalModule module2 = {0xccddccdd, "2",
+ base::FilePath(FILE_PATH_LITERAL("file_path_2"))};
+ InternalFrame frame1 = {0xaaaabbbb, module1};
+ InternalFrame frame2 = {0xaabbaabb, module2};
+
+ std::vector<InternalFrame> frames = {frame1, frame2};
+
+ profile_builder->OnSampleCompleted(frames);
+ profile_builder->OnProfileCompleted(base::TimeDelta::FromMilliseconds(500),
+ base::TimeDelta::FromMilliseconds(100));
+
+ ASSERT_EQ(1u, profile.samples.size());
+ ASSERT_EQ(2u, profile.samples[0].frames.size());
+ EXPECT_EQ(base::TimeDelta::FromMilliseconds(500), profile.profile_duration);
+ EXPECT_EQ(base::TimeDelta::FromMilliseconds(100), profile.sampling_period);
+}
+
+TEST(CallStackProfileBuilderTest, InvalidModule) {
+ CallStackProfile profile;
+
+ // Set up a callback to record the CallStackProfile to local variable
+ // |profile|.
+ auto profile_builder = std::make_unique<CallStackProfileBuilder>(
+ Bind(&SaveProfile, Unretained(&profile)));
+
+ InternalModule module1;
+ InternalModule module2 = {0xccddccdd, "2",
+ base::FilePath(FILE_PATH_LITERAL("file_path_2"))};
+ InternalFrame frame1 = {0xaaaabbbb, module1};
+ InternalFrame frame2 = {0xaabbaabb, module2};
+
+ std::vector<InternalFrame> frames = {frame1, frame2};
+
+ profile_builder->OnSampleCompleted(frames);
+ profile_builder->OnProfileCompleted(base::TimeDelta(), base::TimeDelta());
+
+ ASSERT_EQ(1u, profile.samples.size());
+ ASSERT_EQ(2u, profile.samples[0].frames.size());
+
+ // module1 has no information hence invalid. The module index of the frame is
+ // therefore base::kUnknownModuleIndex.
+ EXPECT_EQ(base::kUnknownModuleIndex,
+ profile.samples[0].frames[0].module_index);
+
+ EXPECT_EQ(0u, profile.samples[0].frames[1].module_index);
+}
+
+TEST(CallStackProfileBuilderTest, DedupModules) {
+ CallStackProfile profile;
+ auto profile_builder = std::make_unique<CallStackProfileBuilder>(
+ Bind(&SaveProfile, Unretained(&profile)));
+
+ InternalModule module1 = {0xccccdddd, "1",
+ base::FilePath(FILE_PATH_LITERAL("file_path_1"))};
+ InternalModule module2 = {0xccccdddd, "2",
+ base::FilePath(FILE_PATH_LITERAL("file_path_2"))};
+ InternalFrame frame1 = {0xaaaabbbb, module1};
+ InternalFrame frame2 = {0xaabbaabb, module2};
+
+ std::vector<InternalFrame> frames = {frame1, frame2};
+
+ profile_builder->OnSampleCompleted(frames);
+ profile_builder->OnProfileCompleted(base::TimeDelta(), base::TimeDelta());
+
+ ASSERT_EQ(1u, profile.samples.size());
+ ASSERT_EQ(2u, profile.samples[0].frames.size());
+
+ // Since module1 and module2 have the same base address 0xccccdddd, they are
+ // considered the same module and therefore deduped.
+ EXPECT_EQ(0u, profile.samples[0].frames[0].module_index);
+ EXPECT_EQ(0u, profile.samples[0].frames[1].module_index);
+}
+
+} // namespace metrics
diff --git a/chromium/components/metrics/call_stack_profile_collector.cc b/chromium/components/metrics/call_stack_profile_collector.cc
index aa127fbf737..dc16a0fc909 100644
--- a/chromium/components/metrics/call_stack_profile_collector.cc
+++ b/chromium/components/metrics/call_stack_profile_collector.cc
@@ -5,7 +5,6 @@
#include "components/metrics/call_stack_profile_collector.h"
#include <utility>
-#include <vector>
#include <memory>
@@ -30,16 +29,15 @@ void CallStackProfileCollector::Create(
std::move(request));
}
-void CallStackProfileCollector::Collect(
- const CallStackProfileParams& params,
- base::TimeTicks start_timestamp,
- std::vector<CallStackProfile> profiles) {
+void CallStackProfileCollector::Collect(const CallStackProfileParams& params,
+ base::TimeTicks start_timestamp,
+ CallStackProfile profile) {
if (params.process != expected_process_)
return;
CallStackProfileParams params_copy = params;
- CallStackProfileMetricsProvider::ReceiveCompletedProfiles(
- params_copy, start_timestamp, std::move(profiles));
+ CallStackProfileMetricsProvider::ReceiveCompletedProfile(
+ params_copy, start_timestamp, std::move(profile));
}
} // namespace metrics
diff --git a/chromium/components/metrics/call_stack_profile_collector.h b/chromium/components/metrics/call_stack_profile_collector.h
index 6eeb6a87b44..97a4db4ca56 100644
--- a/chromium/components/metrics/call_stack_profile_collector.h
+++ b/chromium/components/metrics/call_stack_profile_collector.h
@@ -25,7 +25,7 @@ class CallStackProfileCollector : public mojom::CallStackProfileCollector {
// mojom::CallStackProfileCollector:
void Collect(const CallStackProfileParams& params,
base::TimeTicks start_timestamp,
- std::vector<CallStackProfile> profiles) override;
+ CallStackProfile profile) override;
private:
// Profile params are validated to come from this process. Profiles with a
diff --git a/chromium/components/metrics/call_stack_profile_metrics_provider.cc b/chromium/components/metrics/call_stack_profile_metrics_provider.cc
index bce2bbbb871..9672bbaeb50 100644
--- a/chromium/components/metrics/call_stack_profile_metrics_provider.cc
+++ b/chromium/components/metrics/call_stack_profile_metrics_provider.cc
@@ -24,6 +24,7 @@
#include "base/process/process_info.h"
#include "base/profiler/stack_sampling_profiler.h"
#include "base/single_thread_task_runner.h"
+#include "base/stl_util.h"
#include "base/synchronization/lock.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
@@ -36,6 +37,14 @@ namespace metrics {
namespace {
+// Cap the number of pending profiles to avoid excessive memory usage when
+// profile uploads are delayed (e.g. due to being offline). 1250 profiles
+// corresponds to 80MB of storage. Capping at this threshold loses approximately
+// 0.5% of profiles on canary and dev.
+// TODO(chengx): Remove this threshold after moving to a more memory-efficient
+// profile representation.
+const size_t kMaxPendingProfiles = 1250;
+
// Provide a mapping from the C++ "enum" definition of various process mile-
// stones to the equivalent protobuf "enum" definition. This table-lookup
// conversion allows for the implementation to evolve and still be compatible
@@ -52,16 +61,16 @@ const ProcessPhase
ProcessPhase::SHUTDOWN_START,
};
-// ProfilesState --------------------------------------------------------------
+// ProfileState --------------------------------------------------------------
// A set of profiles and the CallStackProfileMetricsProvider state associated
// with them.
-struct ProfilesState {
- ProfilesState(const CallStackProfileParams& params,
- base::TimeTicks start_timestamp,
- StackSamplingProfiler::CallStackProfiles profiles);
- ProfilesState(ProfilesState&&);
- ProfilesState& operator=(ProfilesState&&);
+struct ProfileState {
+ ProfileState(const CallStackProfileParams& params,
+ base::TimeTicks start_timestamp,
+ StackSamplingProfiler::CallStackProfile profile);
+ ProfileState(ProfileState&&);
+ ProfileState& operator=(ProfileState&&);
// The metrics-related parameters provided to
// CallStackProfileMetricsProvider::GetProfilerCallback().
@@ -70,24 +79,24 @@ struct ProfilesState {
// The time at which the profile collection was started.
base::TimeTicks start_timestamp;
- // The call stack profiles collected by the profiler.
- StackSamplingProfiler::CallStackProfiles profiles;
+ // The call stack profile collected by the profiler.
+ StackSamplingProfiler::CallStackProfile profile;
private:
- DISALLOW_COPY_AND_ASSIGN(ProfilesState);
+ DISALLOW_COPY_AND_ASSIGN(ProfileState);
};
-ProfilesState::ProfilesState(const CallStackProfileParams& params,
- base::TimeTicks start_timestamp,
- StackSamplingProfiler::CallStackProfiles profiles)
+ProfileState::ProfileState(const CallStackProfileParams& params,
+ base::TimeTicks start_timestamp,
+ StackSamplingProfiler::CallStackProfile profile)
: params(params),
start_timestamp(start_timestamp),
- profiles(std::move(profiles)) {}
+ profile(std::move(profile)) {}
-ProfilesState::ProfilesState(ProfilesState&&) = default;
+ProfileState::ProfileState(ProfileState&&) = default;
// Some versions of GCC need this for push_back to work with std::move.
-ProfilesState& ProfilesState::operator=(ProfilesState&&) = default;
+ProfileState& ProfileState::operator=(ProfileState&&) = default;
// PendingProfiles ------------------------------------------------------------
@@ -103,7 +112,7 @@ class PendingProfiles {
public:
static PendingProfiles* GetInstance();
- void Swap(std::vector<ProfilesState>* profiles);
+ void Swap(std::vector<ProfileState>* profiles);
// Enables the collection of profiles by CollectProfilesIfCollectionEnabled if
// |enabled| is true. Otherwise, clears current profiles and ignores profiles
@@ -113,9 +122,9 @@ class PendingProfiles {
// True if profiles are being collected.
bool IsCollectionEnabled() const;
- // Adds |profiles| to the list of profiles if collection is enabled; it is
+ // Adds |profile| to the list of profiles if collection is enabled; it is
// not const& because it must be passed with std::move.
- void CollectProfilesIfCollectionEnabled(ProfilesState profiles);
+ void CollectProfilesIfCollectionEnabled(ProfileState profile);
// Allows testing against the initial state multiple times.
void ResetToDefaultStateForTesting();
@@ -124,7 +133,7 @@ class PendingProfiles {
friend struct base::DefaultSingletonTraits<PendingProfiles>;
PendingProfiles();
- ~PendingProfiles();
+ ~PendingProfiles() = default;
mutable base::Lock lock_;
@@ -137,7 +146,7 @@ class PendingProfiles {
base::TimeTicks last_collection_disable_time_;
// The set of completed profiles that should be reported.
- std::vector<ProfilesState> profiles_;
+ std::vector<ProfileState> profiles_;
DISALLOW_COPY_AND_ASSIGN(PendingProfiles);
};
@@ -149,7 +158,7 @@ PendingProfiles* PendingProfiles::GetInstance() {
base::LeakySingletonTraits<PendingProfiles>>::get();
}
-void PendingProfiles::Swap(std::vector<ProfilesState>* profiles) {
+void PendingProfiles::Swap(std::vector<ProfileState>* profiles) {
base::AutoLock scoped_lock(lock_);
profiles_.swap(*profiles);
}
@@ -170,19 +179,19 @@ bool PendingProfiles::IsCollectionEnabled() const {
return collection_enabled_;
}
-void PendingProfiles::CollectProfilesIfCollectionEnabled(
- ProfilesState profiles) {
+void PendingProfiles::CollectProfilesIfCollectionEnabled(ProfileState profile) {
base::AutoLock scoped_lock(lock_);
// Only collect if collection is not disabled and hasn't been disabled
// since the start of collection for this profile.
if (!collection_enabled_ ||
(!last_collection_disable_time_.is_null() &&
- last_collection_disable_time_ >= profiles.start_timestamp)) {
+ last_collection_disable_time_ >= profile.start_timestamp)) {
return;
}
- profiles_.push_back(std::move(profiles));
+ if (profiles_.size() < kMaxPendingProfiles)
+ profiles_.push_back(std::move(profile));
}
void PendingProfiles::ResetToDefaultStateForTesting() {
@@ -200,23 +209,20 @@ void PendingProfiles::ResetToDefaultStateForTesting() {
// CallStackProfileMetricsProvider.
PendingProfiles::PendingProfiles() : collection_enabled_(true) {}
-PendingProfiles::~PendingProfiles() {}
-
-// Functions to process completed profiles ------------------------------------
+// Functions to process completed profile ------------------------------------
// Will be invoked on either the main thread or the profiler's thread. Provides
-// the profiles to PendingProfiles to append, if the collecting state allows.
-void ReceiveCompletedProfilesImpl(
+// the profile to PendingProfiles to append, if the collecting state allows.
+void ReceiveCompletedProfileImpl(
const CallStackProfileParams& params,
base::TimeTicks start_timestamp,
- StackSamplingProfiler::CallStackProfiles profiles) {
+ StackSamplingProfiler::CallStackProfile profile) {
PendingProfiles::GetInstance()->CollectProfilesIfCollectionEnabled(
- ProfilesState(params, start_timestamp, std::move(profiles)));
+ ProfileState(params, start_timestamp, std::move(profile)));
}
-// Invoked on an arbitrary thread. Ignores the provided profiles.
-void IgnoreCompletedProfiles(
- StackSamplingProfiler::CallStackProfiles profiles) {}
+// Invoked on an arbitrary thread. Ignores the provided profile.
+void IgnoreCompletedProfile(StackSamplingProfiler::CallStackProfile profile) {}
// Functions to encode protobufs ----------------------------------------------
@@ -237,12 +243,12 @@ void CopySampleToProto(
const StackSamplingProfiler::Sample& sample,
const std::vector<StackSamplingProfiler::Module>& modules,
CallStackProfile::Sample* proto_sample) {
- for (const StackSamplingProfiler::Frame& frame : sample.frames) {
+ for (const auto& frame : sample.frames) {
CallStackProfile::Entry* entry = proto_sample->add_entry();
// A frame may not have a valid module. If so, we can't compute the
// instruction pointer offset, and we don't want to send bare pointers, so
// leave call_stack_entry empty.
- if (frame.module_index == StackSamplingProfiler::Frame::kUnknownModuleIndex)
+ if (frame.module_index == base::kUnknownModuleIndex)
continue;
int64_t module_offset =
reinterpret_cast<const char*>(frame.instruction_pointer) -
@@ -264,7 +270,7 @@ void CopyAnnotationsToProto(uint32_t new_milestones,
++bit) {
const uint32_t flag = 1U << bit;
if (new_milestones & flag) {
- if (bit >= arraysize(kProtoPhases)) {
+ if (bit >= base::size(kProtoPhases)) {
NOTREACHED();
continue;
}
@@ -283,7 +289,7 @@ void CopyProfileToProto(
return;
const bool preserve_order =
- (ordering_spec == CallStackProfileParams::PRESERVE_ORDER);
+ ordering_spec == CallStackProfileParams::PRESERVE_ORDER;
std::map<StackSamplingProfiler::Sample, int> sample_index;
uint32_t milestones = 0;
@@ -319,7 +325,7 @@ void CopyProfileToProto(
}
}
- for (const StackSamplingProfiler::Module& module : profile.modules) {
+ for (const auto& module : profile.modules) {
CallStackProfile::ModuleIdentifier* module_id =
proto_profile->add_module_id();
module_id->set_build_id(module.id);
@@ -366,7 +372,7 @@ Thread ToExecutionContextThread(CallStackProfileParams::Thread thread) {
case CallStackProfileParams::UNKNOWN_THREAD:
return UNKNOWN_THREAD;
case CallStackProfileParams::MAIN_THREAD:
- return UI_THREAD;
+ return MAIN_THREAD;
case CallStackProfileParams::IO_THREAD:
return IO_THREAD;
case CallStackProfileParams::COMPOSITOR_THREAD:
@@ -403,31 +409,29 @@ SampledProfile::TriggerEvent ToSampledProfileTriggerEvent(
const base::Feature CallStackProfileMetricsProvider::kEnableReporting = {
"SamplingProfilerReporting", base::FEATURE_DISABLED_BY_DEFAULT};
-CallStackProfileMetricsProvider::CallStackProfileMetricsProvider() {
-}
+CallStackProfileMetricsProvider::CallStackProfileMetricsProvider() {}
-CallStackProfileMetricsProvider::~CallStackProfileMetricsProvider() {
-}
+CallStackProfileMetricsProvider::~CallStackProfileMetricsProvider() {}
-StackSamplingProfiler::CompletedCallback
+CallStackProfileBuilder::CompletedCallback
CallStackProfileMetricsProvider::GetProfilerCallbackForBrowserProcess(
const CallStackProfileParams& params) {
- // Ignore the profiles if the collection is disabled. If the collection state
+ // Ignore the profile if the collection is disabled. If the collection state
// changes while collecting, this will be detected by the callback and
- // profiles will be ignored at that point.
+ // profile will be ignored at that point.
if (!PendingProfiles::GetInstance()->IsCollectionEnabled())
- return base::Bind(&IgnoreCompletedProfiles);
+ return base::Bind(&IgnoreCompletedProfile);
- return base::Bind(&ReceiveCompletedProfilesImpl, params,
+ return base::Bind(&ReceiveCompletedProfileImpl, params,
base::TimeTicks::Now());
}
// static
-void CallStackProfileMetricsProvider::ReceiveCompletedProfiles(
+void CallStackProfileMetricsProvider::ReceiveCompletedProfile(
const CallStackProfileParams& params,
base::TimeTicks profile_start_time,
- base::StackSamplingProfiler::CallStackProfiles profiles) {
- ReceiveCompletedProfilesImpl(params, profile_start_time, std::move(profiles));
+ StackSamplingProfiler::CallStackProfile profile) {
+ ReceiveCompletedProfileImpl(params, profile_start_time, std::move(profile));
}
void CallStackProfileMetricsProvider::OnRecordingEnabled() {
@@ -441,25 +445,23 @@ void CallStackProfileMetricsProvider::OnRecordingDisabled() {
void CallStackProfileMetricsProvider::ProvideCurrentSessionData(
ChromeUserMetricsExtension* uma_proto) {
- std::vector<ProfilesState> pending_profiles;
+ std::vector<ProfileState> pending_profiles;
PendingProfiles::GetInstance()->Swap(&pending_profiles);
DCHECK(base::FeatureList::IsEnabled(kEnableReporting) ||
pending_profiles.empty());
- for (const ProfilesState& profiles_state : pending_profiles) {
- for (const StackSamplingProfiler::CallStackProfile& profile :
- profiles_state.profiles) {
- SampledProfile* sampled_profile = uma_proto->add_sampled_profile();
- sampled_profile->set_process(
- ToExecutionContextProcess(profiles_state.params.process));
- sampled_profile->set_thread(
- ToExecutionContextThread(profiles_state.params.thread));
- sampled_profile->set_trigger_event(
- ToSampledProfileTriggerEvent(profiles_state.params.trigger));
- CopyProfileToProto(profile, profiles_state.params.ordering_spec,
- sampled_profile->mutable_call_stack_profile());
- }
+ for (const auto& profile_state : pending_profiles) {
+ SampledProfile* sampled_profile = uma_proto->add_sampled_profile();
+ sampled_profile->set_process(
+ ToExecutionContextProcess(profile_state.params.process));
+ sampled_profile->set_thread(
+ ToExecutionContextThread(profile_state.params.thread));
+ sampled_profile->set_trigger_event(
+ ToSampledProfileTriggerEvent(profile_state.params.trigger));
+ CopyProfileToProto(profile_state.profile,
+ profile_state.params.ordering_spec,
+ sampled_profile->mutable_call_stack_profile());
}
}
diff --git a/chromium/components/metrics/call_stack_profile_metrics_provider.h b/chromium/components/metrics/call_stack_profile_metrics_provider.h
index f995a9a411b..4b05c4e896d 100644
--- a/chromium/components/metrics/call_stack_profile_metrics_provider.h
+++ b/chromium/components/metrics/call_stack_profile_metrics_provider.h
@@ -5,12 +5,11 @@
#ifndef COMPONENTS_METRICS_CALL_STACK_PROFILE_METRICS_PROVIDER_H_
#define COMPONENTS_METRICS_CALL_STACK_PROFILE_METRICS_PROVIDER_H_
-#include <vector>
-
#include "base/feature_list.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/profiler/stack_sampling_profiler.h"
+#include "components/metrics/call_stack_profile_builder.h"
#include "components/metrics/call_stack_profile_params.h"
#include "components/metrics/metrics_provider.h"
@@ -22,8 +21,9 @@ class ChromeUserMetricsExtension;
class CallStackProfileMetricsProvider : public MetricsProvider {
public:
// These milestones of a process lifetime can be passed as process "mile-
- // stones" to StackSmaplingProfile::SetProcessMilestone(). Be sure to update
- // the translation constants at the top of the .cc file when this is changed.
+ // stones" to CallStackProfileBuilder::SetProcessMilestone(). Be sure to
+ // update the translation constants at the top of the .cc file when this is
+ // changed.
enum Milestones : int {
MAIN_LOOP_START,
MAIN_NAVIGATION_START,
@@ -38,20 +38,21 @@ class CallStackProfileMetricsProvider : public MetricsProvider {
CallStackProfileMetricsProvider();
~CallStackProfileMetricsProvider() override;
- // Returns a callback for use with StackSamplingProfiler that sets up
+ // Returns a callback for use with CallStackProfileBuilder that sets up
// parameters for general browser process sampling. The callback should be
- // immediately passed to the StackSamplingProfiler, and should not be reused.
- static base::StackSamplingProfiler::CompletedCallback
+ // immediately passed to the CallStackProfileBuilder, and should not be
+ // reused.
+ static CallStackProfileBuilder::CompletedCallback
GetProfilerCallbackForBrowserProcess(const CallStackProfileParams& params);
- // Provides completed stack profiles to the metrics provider. Intended for use
+ // Provides completed stack profile to the metrics provider. Intended for use
// when receiving profiles over IPC. In-process StackSamplingProfiler users
- // should instead use a variant of GetProfilerCallback*(). |profiles| is not
+ // should instead use a variant of GetProfilerCallback*(). |profile| is not
// const& because it must be passed with std::move.
- static void ReceiveCompletedProfiles(
+ static void ReceiveCompletedProfile(
const CallStackProfileParams& params,
base::TimeTicks profile_start_time,
- base::StackSamplingProfiler::CallStackProfiles profiles);
+ base::StackSamplingProfiler::CallStackProfile profile);
// MetricsProvider:
void OnRecordingEnabled() override;
diff --git a/chromium/components/metrics/call_stack_profile_metrics_provider_unittest.cc b/chromium/components/metrics/call_stack_profile_metrics_provider_unittest.cc
index c4777110ef4..309235c3732 100644
--- a/chromium/components/metrics/call_stack_profile_metrics_provider_unittest.cc
+++ b/chromium/components/metrics/call_stack_profile_metrics_provider_unittest.cc
@@ -12,6 +12,7 @@
#include "base/macros.h"
#include "base/profiler/stack_sampling_profiler.h"
#include "base/run_loop.h"
+#include "base/stl_util.h"
#include "base/strings/string_number_conversions.h"
#include "base/test/scoped_feature_list.h"
#include "build/build_config.h"
@@ -23,9 +24,8 @@
using base::StackSamplingProfiler;
using Frame = StackSamplingProfiler::Frame;
using Module = StackSamplingProfiler::Module;
-using Profile = StackSamplingProfiler::CallStackProfile;
-using Profiles = StackSamplingProfiler::CallStackProfiles;
using Sample = StackSamplingProfiler::Sample;
+using Profile = StackSamplingProfiler::CallStackProfile;
namespace {
@@ -56,61 +56,55 @@ struct ExpectedProtoProfile {
int sample_count;
};
-class ProfilesFactory {
+class ProfileFactory {
public:
- ProfilesFactory() {}
- ~ProfilesFactory() {}
+ ProfileFactory(int duration_ms, int interval_ms) {
+ profile_.profile_duration = base::TimeDelta::FromMilliseconds(duration_ms);
+ profile_.sampling_period = base::TimeDelta::FromMilliseconds(interval_ms);
+ }
+ ~ProfileFactory() {}
- ProfilesFactory& AddMilestone(int milestone);
- ProfilesFactory& NewProfile(int duration_ms, int interval_ms);
- ProfilesFactory& NewSample();
- ProfilesFactory& AddFrame(size_t module, uintptr_t offset);
- ProfilesFactory& DefineModule(const char* name,
- const base::FilePath& path,
- uintptr_t base);
+ ProfileFactory& AddMilestone(int milestone);
+ ProfileFactory& NewSample();
+ ProfileFactory& AddFrame(size_t module, uintptr_t offset);
+ ProfileFactory& DefineModule(const char* name,
+ const base::FilePath& path,
+ uintptr_t base);
- Profiles Build();
+ Profile Build();
private:
- Profiles profiles_;
+ Profile profile_;
uint32_t process_milestones_ = 0;
- DISALLOW_COPY_AND_ASSIGN(ProfilesFactory);
+ DISALLOW_COPY_AND_ASSIGN(ProfileFactory);
};
-ProfilesFactory& ProfilesFactory::AddMilestone(int milestone) {
+ProfileFactory& ProfileFactory::AddMilestone(int milestone) {
process_milestones_ |= 1 << milestone;
return *this;
}
-ProfilesFactory& ProfilesFactory::NewProfile(int duration_ms, int interval_ms) {
- profiles_.push_back(Profile());
- Profile* profile = &profiles_.back();
- profile->profile_duration = base::TimeDelta::FromMilliseconds(duration_ms);
- profile->sampling_period = base::TimeDelta::FromMilliseconds(interval_ms);
+ProfileFactory& ProfileFactory::NewSample() {
+ profile_.samples.push_back(Sample());
+ profile_.samples.back().process_milestones = process_milestones_;
return *this;
}
-ProfilesFactory& ProfilesFactory::NewSample() {
- profiles_.back().samples.push_back(Sample());
- profiles_.back().samples.back().process_milestones = process_milestones_;
+ProfileFactory& ProfileFactory::AddFrame(size_t module, uintptr_t offset) {
+ profile_.samples.back().frames.push_back(Frame(offset, module));
return *this;
}
-ProfilesFactory& ProfilesFactory::AddFrame(size_t module, uintptr_t offset) {
- profiles_.back().samples.back().frames.push_back(Frame(offset, module));
+ProfileFactory& ProfileFactory::DefineModule(const char* name,
+ const base::FilePath& path,
+ uintptr_t base) {
+ profile_.modules.push_back(Module(base, name, path));
return *this;
}
-ProfilesFactory& ProfilesFactory::DefineModule(const char* name,
- const base::FilePath& path,
- uintptr_t base) {
- profiles_.back().modules.push_back(Module(base, name, path));
- return *this;
-}
-
-Profiles ProfilesFactory::Build() {
- return std::move(profiles_);
+Profile ProfileFactory::Build() {
+ return std::move(profile_);
}
} // namespace
@@ -118,7 +112,7 @@ Profiles ProfilesFactory::Build() {
namespace metrics {
// This test fixture enables the feature that
-// CallStackProfileMetricsProvider depends on to report profiles.
+// CallStackProfileMetricsProvider depends on to report a profile.
class CallStackProfileMetricsProviderTest : public testing::Test {
public:
CallStackProfileMetricsProviderTest() {
@@ -128,11 +122,11 @@ class CallStackProfileMetricsProviderTest : public testing::Test {
~CallStackProfileMetricsProviderTest() override {}
- // Utility function to append profiles to the metrics provider.
- void AppendProfiles(const CallStackProfileParams& params, Profiles profiles) {
+ // Utility function to append a profile to the metrics provider.
+ void AppendProfile(const CallStackProfileParams& params, Profile profile) {
CallStackProfileMetricsProvider::GetProfilerCallbackForBrowserProcess(
params)
- .Run(std::move(profiles));
+ .Run(std::move(profile));
}
void VerifyProfileProto(const ExpectedProtoProfile& expected,
@@ -203,160 +197,6 @@ void CallStackProfileMetricsProviderTest::VerifyProfileProto(
}
}
-// Checks that all properties from multiple profiles are filled as expected.
-TEST_F(CallStackProfileMetricsProviderTest, MultipleProfiles) {
- const uintptr_t moduleA_base_address = 0x1000;
- const uintptr_t moduleB_base_address = 0x2000;
- const uintptr_t moduleC_base_address = 0x3000;
- const char* moduleA_name = "ABCD";
- const char* moduleB_name = "EFGH";
- const char* moduleC_name = "MNOP";
-
- // Values for Windows generated with:
- // perl -MDigest::MD5=md5 -MEncode=encode
- // -e 'for(@ARGV){printf "%x\n", unpack "Q>", md5 encode "UTF-16LE", $_}'
- // chrome.exe third_party.dll third_party2.dll
- //
- // Values for Linux generated with:
- // perl -MDigest::MD5=md5
- // -e 'for(@ARGV){printf "%x\n", unpack "Q>", md5 $_}'
- // chrome third_party.so third_party2.so
-#if defined(OS_WIN)
- uint64_t moduleA_md5 = 0x46C3E4166659AC02ULL;
- uint64_t moduleB_md5 = 0x7E2B8BFDDEAE1ABAULL;
- uint64_t moduleC_md5 = 0x87B66F4573A4D5CAULL;
- base::FilePath moduleA_path(L"c:\\some\\path\\to\\chrome.exe");
- base::FilePath moduleB_path(L"c:\\some\\path\\to\\third_party.dll");
- base::FilePath moduleC_path(L"c:\\some\\path\\to\\third_party2.dll");
-#else
- uint64_t moduleA_md5 = 0x554838A8451AC36CULL;
- uint64_t moduleB_md5 = 0x843661148659C9F8ULL;
- uint64_t moduleC_md5 = 0xB4647E539FA6EC9EULL;
- base::FilePath moduleA_path("/some/path/to/chrome");
- base::FilePath moduleB_path("/some/path/to/third_party.so");
- base::FilePath moduleC_path("/some/path/to/third_party2.so");
-#endif
-
- // Represents two stack samples for each of two profiles, where each stack
- // contains three frames. Each frame contains an instruction pointer and a
- // module index corresponding to the module for the profile in
- // profile_modules.
- //
- // So, the first stack sample below has its top frame in module 0 at an offset
- // of 0x10 from the module's base address, the next-to-top frame in module 1
- // at an offset of 0x20 from the module's base address, and the bottom frame
- // in module 0 at an offset of 0x30 from the module's base address
- Profiles profiles = ProfilesFactory()
- .NewProfile(100, 10)
- .DefineModule(moduleA_name, moduleA_path, moduleA_base_address)
- .DefineModule(moduleB_name, moduleB_path, moduleB_base_address)
-
- .NewSample()
- .AddFrame(0, moduleA_base_address + 0x10)
- .AddFrame(1, moduleB_base_address + 0x20)
- .AddFrame(0, moduleA_base_address + 0x30)
- .NewSample()
- .AddFrame(1, moduleB_base_address + 0x10)
- .AddFrame(0, moduleA_base_address + 0x20)
- .AddFrame(1, moduleB_base_address + 0x30)
-
- .NewProfile(200, 20)
- .DefineModule(moduleC_name, moduleC_path, moduleC_base_address)
- .DefineModule(moduleA_name, moduleA_path, moduleA_base_address)
-
- .NewSample()
- .AddFrame(0, moduleC_base_address + 0x10)
- .AddFrame(1, moduleA_base_address + 0x20)
- .AddFrame(0, moduleC_base_address + 0x30)
- .NewSample()
- .AddFrame(1, moduleA_base_address + 0x10)
- .AddFrame(0, moduleC_base_address + 0x20)
- .AddFrame(1, moduleA_base_address + 0x30)
-
- .Build();
-
- const ExpectedProtoModule expected_proto_modules1[] = {
- { moduleA_name, moduleA_md5, moduleA_base_address },
- { moduleB_name, moduleB_md5, moduleB_base_address }
- };
-
- const ExpectedProtoEntry expected_proto_entries11[] = {
- { 0, 0x10 },
- { 1, 0x20 },
- { 0, 0x30 },
- };
- const ExpectedProtoEntry expected_proto_entries12[] = {
- { 1, 0x10 },
- { 0, 0x20 },
- { 1, 0x30 },
- };
- const ExpectedProtoSample expected_proto_samples1[] = {
- {
- 0, expected_proto_entries11, arraysize(expected_proto_entries11), 1,
- },
- {
- 0, expected_proto_entries12, arraysize(expected_proto_entries12), 1,
- },
- };
-
- const ExpectedProtoModule expected_proto_modules2[] = {
- { moduleC_name, moduleC_md5, moduleC_base_address },
- { moduleA_name, moduleA_md5, moduleA_base_address }
- };
-
- const ExpectedProtoEntry expected_proto_entries21[] = {
- { 0, 0x10 },
- { 1, 0x20 },
- { 0, 0x30 },
- };
- const ExpectedProtoEntry expected_proto_entries22[] = {
- { 1, 0x10 },
- { 0, 0x20 },
- { 1, 0x30 },
- };
- const ExpectedProtoSample expected_proto_samples2[] = {
- {
- 0, expected_proto_entries11, arraysize(expected_proto_entries21), 1,
- },
- {
- 0, expected_proto_entries12, arraysize(expected_proto_entries22), 1,
- },
- };
-
- const ExpectedProtoProfile expected_proto_profiles[] = {
- {
- 100, 10,
- expected_proto_modules1, arraysize(expected_proto_modules1),
- expected_proto_samples1, arraysize(expected_proto_samples1),
- },
- {
- 200, 20,
- expected_proto_modules2, arraysize(expected_proto_modules2),
- expected_proto_samples2, arraysize(expected_proto_samples2),
- },
- };
-
- ASSERT_EQ(arraysize(expected_proto_profiles), profiles.size());
-
- CallStackProfileMetricsProvider provider;
- provider.OnRecordingEnabled();
- CallStackProfileParams params(CallStackProfileParams::BROWSER_PROCESS,
- CallStackProfileParams::MAIN_THREAD,
- CallStackProfileParams::PROCESS_STARTUP,
- CallStackProfileParams::MAY_SHUFFLE);
- AppendProfiles(params, std::move(profiles));
- ChromeUserMetricsExtension uma_proto;
- provider.ProvideCurrentSessionData(&uma_proto);
-
- ASSERT_EQ(static_cast<int>(arraysize(expected_proto_profiles)),
- uma_proto.sampled_profile().size());
- for (size_t p = 0; p < arraysize(expected_proto_profiles); ++p) {
- SCOPED_TRACE("profile " + base::NumberToString(p));
- VerifyProfileProto(expected_proto_profiles[p],
- uma_proto.sampled_profile().Get(p));
- }
-}
-
// Checks that all duplicate samples are collapsed with
// preserve_sample_ordering = false.
TEST_F(CallStackProfileMetricsProviderTest, RepeatedStacksUnordered) {
@@ -371,31 +211,31 @@ TEST_F(CallStackProfileMetricsProviderTest, RepeatedStacksUnordered) {
base::FilePath module_path("/some/path/to/chrome");
#endif
- Profiles profiles = ProfilesFactory()
- .NewProfile(100, 10)
- .DefineModule(module_name, module_path, module_base_address)
-
- .AddMilestone(0)
- .NewSample()
- .AddFrame(0, module_base_address + 0x10)
- .NewSample()
- .AddFrame(0, module_base_address + 0x20)
- .NewSample()
- .AddFrame(0, module_base_address + 0x10)
- .NewSample()
- .AddFrame(0, module_base_address + 0x10)
-
- .AddMilestone(1)
- .NewSample()
- .AddFrame(0, module_base_address + 0x10)
- .NewSample()
- .AddFrame(0, module_base_address + 0x20)
- .NewSample()
- .AddFrame(0, module_base_address + 0x10)
- .NewSample()
- .AddFrame(0, module_base_address + 0x10)
-
- .Build();
+ Profile profile =
+ ProfileFactory(100, 10)
+ .DefineModule(module_name, module_path, module_base_address)
+
+ .AddMilestone(0)
+ .NewSample()
+ .AddFrame(0, module_base_address + 0x10)
+ .NewSample()
+ .AddFrame(0, module_base_address + 0x20)
+ .NewSample()
+ .AddFrame(0, module_base_address + 0x10)
+ .NewSample()
+ .AddFrame(0, module_base_address + 0x10)
+
+ .AddMilestone(1)
+ .NewSample()
+ .AddFrame(0, module_base_address + 0x10)
+ .NewSample()
+ .AddFrame(0, module_base_address + 0x20)
+ .NewSample()
+ .AddFrame(0, module_base_address + 0x10)
+ .NewSample()
+ .AddFrame(0, module_base_address + 0x10)
+
+ .Build();
const ExpectedProtoModule expected_proto_modules[] = {
{ module_name, module_md5, module_base_address },
@@ -412,33 +252,28 @@ TEST_F(CallStackProfileMetricsProviderTest, RepeatedStacksUnordered) {
{ 0, &expected_proto_entries[1], 1, 1 },
};
- const ExpectedProtoProfile expected_proto_profiles[] = {
- {
- 100, 10,
- expected_proto_modules, arraysize(expected_proto_modules),
- expected_proto_samples, arraysize(expected_proto_samples),
- },
+ const ExpectedProtoProfile expected_proto_profile = {
+ 100,
+ 10,
+ expected_proto_modules,
+ base::size(expected_proto_modules),
+ expected_proto_samples,
+ base::size(expected_proto_samples),
};
- ASSERT_EQ(arraysize(expected_proto_profiles), profiles.size());
-
CallStackProfileMetricsProvider provider;
provider.OnRecordingEnabled();
CallStackProfileParams params(CallStackProfileParams::BROWSER_PROCESS,
CallStackProfileParams::MAIN_THREAD,
CallStackProfileParams::PROCESS_STARTUP,
CallStackProfileParams::MAY_SHUFFLE);
- AppendProfiles(params, std::move(profiles));
+ AppendProfile(params, std::move(profile));
ChromeUserMetricsExtension uma_proto;
provider.ProvideCurrentSessionData(&uma_proto);
- ASSERT_EQ(static_cast<int>(arraysize(expected_proto_profiles)),
- uma_proto.sampled_profile().size());
- for (size_t p = 0; p < arraysize(expected_proto_profiles); ++p) {
- SCOPED_TRACE("profile " + base::NumberToString(p));
- VerifyProfileProto(expected_proto_profiles[p],
- uma_proto.sampled_profile().Get(p));
- }
+ ASSERT_EQ(1, uma_proto.sampled_profile().size());
+ VerifyProfileProto(expected_proto_profile,
+ uma_proto.sampled_profile().Get(0));
}
// Checks that only contiguous duplicate samples are collapsed with
@@ -455,31 +290,31 @@ TEST_F(CallStackProfileMetricsProviderTest, RepeatedStacksOrdered) {
base::FilePath module_path("/some/path/to/chrome");
#endif
- Profiles profiles = ProfilesFactory()
- .NewProfile(100, 10)
- .DefineModule(module_name, module_path, module_base_address)
-
- .AddMilestone(0)
- .NewSample()
- .AddFrame(0, module_base_address + 0x10)
- .NewSample()
- .AddFrame(0, module_base_address + 0x20)
- .NewSample()
- .AddFrame(0, module_base_address + 0x10)
- .NewSample()
- .AddFrame(0, module_base_address + 0x10)
-
- .AddMilestone(1)
- .NewSample()
- .AddFrame(0, module_base_address + 0x10)
- .NewSample()
- .AddFrame(0, module_base_address + 0x20)
- .NewSample()
- .AddFrame(0, module_base_address + 0x10)
- .NewSample()
- .AddFrame(0, module_base_address + 0x10)
-
- .Build();
+ Profile profile =
+ ProfileFactory(100, 10)
+ .DefineModule(module_name, module_path, module_base_address)
+
+ .AddMilestone(0)
+ .NewSample()
+ .AddFrame(0, module_base_address + 0x10)
+ .NewSample()
+ .AddFrame(0, module_base_address + 0x20)
+ .NewSample()
+ .AddFrame(0, module_base_address + 0x10)
+ .NewSample()
+ .AddFrame(0, module_base_address + 0x10)
+
+ .AddMilestone(1)
+ .NewSample()
+ .AddFrame(0, module_base_address + 0x10)
+ .NewSample()
+ .AddFrame(0, module_base_address + 0x20)
+ .NewSample()
+ .AddFrame(0, module_base_address + 0x10)
+ .NewSample()
+ .AddFrame(0, module_base_address + 0x10)
+
+ .Build();
const ExpectedProtoModule expected_proto_modules[] = {
{ module_name, module_md5, module_base_address },
@@ -498,42 +333,36 @@ TEST_F(CallStackProfileMetricsProviderTest, RepeatedStacksOrdered) {
{ 0, &expected_proto_entries[0], 1, 2 },
};
- const ExpectedProtoProfile expected_proto_profiles[] = {
- {
- 100, 10,
- expected_proto_modules, arraysize(expected_proto_modules),
- expected_proto_samples, arraysize(expected_proto_samples),
- },
+ const ExpectedProtoProfile expected_proto_profile = {
+ 100,
+ 10,
+ expected_proto_modules,
+ base::size(expected_proto_modules),
+ expected_proto_samples,
+ base::size(expected_proto_samples),
};
- ASSERT_EQ(arraysize(expected_proto_profiles), profiles.size());
-
CallStackProfileMetricsProvider provider;
provider.OnRecordingEnabled();
CallStackProfileParams params(CallStackProfileParams::BROWSER_PROCESS,
CallStackProfileParams::MAIN_THREAD,
CallStackProfileParams::PROCESS_STARTUP,
CallStackProfileParams::PRESERVE_ORDER);
- AppendProfiles(params, std::move(profiles));
+ AppendProfile(params, std::move(profile));
ChromeUserMetricsExtension uma_proto;
provider.ProvideCurrentSessionData(&uma_proto);
- ASSERT_EQ(static_cast<int>(arraysize(expected_proto_profiles)),
- uma_proto.sampled_profile().size());
- for (size_t p = 0; p < arraysize(expected_proto_profiles); ++p) {
- SCOPED_TRACE("profile " + base::NumberToString(p));
- VerifyProfileProto(expected_proto_profiles[p],
- uma_proto.sampled_profile().Get(p));
- }
+ ASSERT_EQ(1, uma_proto.sampled_profile().size());
+ VerifyProfileProto(expected_proto_profile,
+ uma_proto.sampled_profile().Get(0));
}
// Checks that unknown modules produce an empty Entry.
TEST_F(CallStackProfileMetricsProviderTest, UnknownModule) {
- Profiles profiles = ProfilesFactory()
- .NewProfile(100, 10)
- .NewSample()
- .AddFrame(Frame::kUnknownModuleIndex, 0x1234)
- .Build();
+ Profile profile = ProfileFactory(100, 10)
+ .NewSample()
+ .AddFrame(base::kUnknownModuleIndex, 0x1234)
+ .Build();
const ExpectedProtoEntry expected_proto_entries[] = {
{ -1, 0 },
@@ -542,48 +371,41 @@ TEST_F(CallStackProfileMetricsProviderTest, UnknownModule) {
{ 0, &expected_proto_entries[0], 1, 1 },
};
- const ExpectedProtoProfile expected_proto_profiles[] = {
- {
- 100, 10,
- nullptr, 0,
- expected_proto_samples, arraysize(expected_proto_samples),
- },
+ const ExpectedProtoProfile expected_proto_profile = {
+ 100,
+ 10,
+ nullptr,
+ 0,
+ expected_proto_samples,
+ base::size(expected_proto_samples),
};
- ASSERT_EQ(arraysize(expected_proto_profiles), profiles.size());
-
CallStackProfileMetricsProvider provider;
provider.OnRecordingEnabled();
CallStackProfileParams params(CallStackProfileParams::BROWSER_PROCESS,
CallStackProfileParams::MAIN_THREAD,
CallStackProfileParams::PROCESS_STARTUP,
CallStackProfileParams::MAY_SHUFFLE);
- AppendProfiles(params, std::move(profiles));
+ AppendProfile(params, std::move(profile));
ChromeUserMetricsExtension uma_proto;
provider.ProvideCurrentSessionData(&uma_proto);
- ASSERT_EQ(static_cast<int>(arraysize(expected_proto_profiles)),
- uma_proto.sampled_profile().size());
- for (size_t p = 0; p < arraysize(expected_proto_profiles); ++p) {
- SCOPED_TRACE("profile " + base::NumberToString(p));
- VerifyProfileProto(expected_proto_profiles[p],
- uma_proto.sampled_profile().Get(p));
- }
+ ASSERT_EQ(1, uma_proto.sampled_profile().size());
+ VerifyProfileProto(expected_proto_profile,
+ uma_proto.sampled_profile().Get(0));
}
-// Checks that pending profiles are only passed back to
+// Checks that the pending profile is only passed back to
// ProvideCurrentSessionData once.
-TEST_F(CallStackProfileMetricsProviderTest, ProfilesProvidedOnlyOnce) {
+TEST_F(CallStackProfileMetricsProviderTest, ProfileProvidedOnlyOnce) {
CallStackProfileMetricsProvider provider;
for (int r = 0; r < 2; ++r) {
- Profiles profiles = ProfilesFactory()
+ Profile profile =
// Use the sampling period to distinguish the two profiles.
- .NewProfile(100, r)
- .NewSample()
- .AddFrame(Frame::kUnknownModuleIndex, 0x1234)
- .Build();
-
- ASSERT_EQ(1U, profiles.size());
+ ProfileFactory(100, r)
+ .NewSample()
+ .AddFrame(base::kUnknownModuleIndex, 0x1234)
+ .Build();
CallStackProfileMetricsProvider provider;
provider.OnRecordingEnabled();
@@ -591,7 +413,7 @@ TEST_F(CallStackProfileMetricsProviderTest, ProfilesProvidedOnlyOnce) {
CallStackProfileParams::MAIN_THREAD,
CallStackProfileParams::PROCESS_STARTUP,
CallStackProfileParams::MAY_SHUFFLE);
- AppendProfiles(params, std::move(profiles));
+ AppendProfile(params, std::move(profile));
ChromeUserMetricsExtension uma_proto;
provider.ProvideCurrentSessionData(&uma_proto);
@@ -605,23 +427,20 @@ TEST_F(CallStackProfileMetricsProviderTest, ProfilesProvidedOnlyOnce) {
}
}
-// Checks that pending profiles are provided to ProvideCurrentSessionData
+// Checks that the pending profile is provided to ProvideCurrentSessionData
// when collected before CallStackProfileMetricsProvider is instantiated.
TEST_F(CallStackProfileMetricsProviderTest,
- ProfilesProvidedWhenCollectedBeforeInstantiation) {
- Profiles profiles = ProfilesFactory()
- .NewProfile(100, 10)
- .NewSample()
- .AddFrame(Frame::kUnknownModuleIndex, 0x1234)
- .Build();
-
- ASSERT_EQ(1U, profiles.size());
+ ProfileProvidedWhenCollectedBeforeInstantiation) {
+ Profile profile = ProfileFactory(100, 10)
+ .NewSample()
+ .AddFrame(base::kUnknownModuleIndex, 0x1234)
+ .Build();
CallStackProfileParams params(CallStackProfileParams::BROWSER_PROCESS,
CallStackProfileParams::MAIN_THREAD,
CallStackProfileParams::PROCESS_STARTUP,
CallStackProfileParams::MAY_SHUFFLE);
- AppendProfiles(params, std::move(profiles));
+ AppendProfile(params, std::move(profile));
CallStackProfileMetricsProvider provider;
provider.OnRecordingEnabled();
@@ -631,16 +450,13 @@ TEST_F(CallStackProfileMetricsProviderTest,
EXPECT_EQ(1, uma_proto.sampled_profile_size());
}
-// Checks that pending profiles are not provided to ProvideCurrentSessionData
+// Checks that the pending profile is not provided to ProvideCurrentSessionData
// while recording is disabled.
-TEST_F(CallStackProfileMetricsProviderTest, ProfilesNotProvidedWhileDisabled) {
- Profiles profiles = ProfilesFactory()
- .NewProfile(100, 10)
- .NewSample()
- .AddFrame(Frame::kUnknownModuleIndex, 0x1234)
- .Build();
-
- ASSERT_EQ(1U, profiles.size());
+TEST_F(CallStackProfileMetricsProviderTest, ProfileNotProvidedWhileDisabled) {
+ Profile profile = ProfileFactory(100, 10)
+ .NewSample()
+ .AddFrame(base::kUnknownModuleIndex, 0x1234)
+ .Build();
CallStackProfileMetricsProvider provider;
provider.OnRecordingDisabled();
@@ -648,89 +464,86 @@ TEST_F(CallStackProfileMetricsProviderTest, ProfilesNotProvidedWhileDisabled) {
CallStackProfileParams::MAIN_THREAD,
CallStackProfileParams::PROCESS_STARTUP,
CallStackProfileParams::MAY_SHUFFLE);
- AppendProfiles(params, std::move(profiles));
+ AppendProfile(params, std::move(profile));
ChromeUserMetricsExtension uma_proto;
provider.ProvideCurrentSessionData(&uma_proto);
EXPECT_EQ(0, uma_proto.sampled_profile_size());
}
-// Checks that pending profiles are not provided to ProvideCurrentSessionData
+// Checks that the pending profile is not provided to ProvideCurrentSessionData
// if recording is disabled while profiling.
TEST_F(CallStackProfileMetricsProviderTest,
- ProfilesNotProvidedAfterChangeToDisabled) {
+ ProfileNotProvidedAfterChangeToDisabled) {
CallStackProfileMetricsProvider provider;
provider.OnRecordingEnabled();
CallStackProfileParams params(CallStackProfileParams::BROWSER_PROCESS,
CallStackProfileParams::MAIN_THREAD,
CallStackProfileParams::PROCESS_STARTUP,
CallStackProfileParams::MAY_SHUFFLE);
- base::StackSamplingProfiler::CompletedCallback callback =
+ CallStackProfileBuilder::CompletedCallback callback =
CallStackProfileMetricsProvider::GetProfilerCallbackForBrowserProcess(
params);
provider.OnRecordingDisabled();
- Profiles profiles = ProfilesFactory()
- .NewProfile(100, 10)
- .NewSample()
- .AddFrame(Frame::kUnknownModuleIndex, 0x1234)
- .Build();
- callback.Run(std::move(profiles));
+ Profile profile = ProfileFactory(100, 10)
+ .NewSample()
+ .AddFrame(base::kUnknownModuleIndex, 0x1234)
+ .Build();
+ callback.Run(std::move(profile));
ChromeUserMetricsExtension uma_proto;
provider.ProvideCurrentSessionData(&uma_proto);
EXPECT_EQ(0, uma_proto.sampled_profile_size());
}
-// Checks that pending profiles are not provided to ProvideCurrentSessionData if
-// recording is enabled, but then disabled and reenabled while profiling.
+// Checks that the pending profile is not provided to ProvideCurrentSessionData
+// if recording is enabled, but then disabled and reenabled while profiling.
TEST_F(CallStackProfileMetricsProviderTest,
- ProfilesNotProvidedAfterChangeToDisabledThenEnabled) {
+ ProfileNotProvidedAfterChangeToDisabledThenEnabled) {
CallStackProfileMetricsProvider provider;
provider.OnRecordingEnabled();
CallStackProfileParams params(CallStackProfileParams::BROWSER_PROCESS,
CallStackProfileParams::MAIN_THREAD,
CallStackProfileParams::PROCESS_STARTUP,
CallStackProfileParams::MAY_SHUFFLE);
- base::StackSamplingProfiler::CompletedCallback callback =
+ CallStackProfileBuilder::CompletedCallback callback =
CallStackProfileMetricsProvider::GetProfilerCallbackForBrowserProcess(
params);
provider.OnRecordingDisabled();
provider.OnRecordingEnabled();
- Profiles profiles = ProfilesFactory()
- .NewProfile(100, 10)
- .NewSample()
- .AddFrame(Frame::kUnknownModuleIndex, 0x1234)
- .Build();
- callback.Run(std::move(profiles));
+ Profile profile = ProfileFactory(100, 10)
+ .NewSample()
+ .AddFrame(base::kUnknownModuleIndex, 0x1234)
+ .Build();
+ callback.Run(std::move(profile));
ChromeUserMetricsExtension uma_proto;
provider.ProvideCurrentSessionData(&uma_proto);
EXPECT_EQ(0, uma_proto.sampled_profile_size());
}
-// Checks that pending profiles are not provided to ProvideCurrentSessionData
+// Checks that the pending profile is not provided to ProvideCurrentSessionData
// if recording is disabled, but then enabled while profiling.
TEST_F(CallStackProfileMetricsProviderTest,
- ProfilesNotProvidedAfterChangeFromDisabled) {
+ ProfileNotProvidedAfterChangeFromDisabled) {
CallStackProfileMetricsProvider provider;
provider.OnRecordingDisabled();
CallStackProfileParams params(CallStackProfileParams::BROWSER_PROCESS,
CallStackProfileParams::MAIN_THREAD,
CallStackProfileParams::PROCESS_STARTUP,
CallStackProfileParams::MAY_SHUFFLE);
- base::StackSamplingProfiler::CompletedCallback callback =
+ CallStackProfileBuilder::CompletedCallback callback =
CallStackProfileMetricsProvider::GetProfilerCallbackForBrowserProcess(
params);
provider.OnRecordingEnabled();
- Profiles profiles = ProfilesFactory()
- .NewProfile(100, 10)
- .NewSample()
- .AddFrame(Frame::kUnknownModuleIndex, 0x1234)
- .Build();
- callback.Run(std::move(profiles));
+ Profile profile = ProfileFactory(100, 10)
+ .NewSample()
+ .AddFrame(base::kUnknownModuleIndex, 0x1234)
+ .Build();
+ callback.Run(std::move(profile));
ChromeUserMetricsExtension uma_proto;
provider.ProvideCurrentSessionData(&uma_proto);
diff --git a/chromium/components/metrics/child_call_stack_profile_collector.cc b/chromium/components/metrics/child_call_stack_profile_collector.cc
index 978ecd7382c..3cdfc55e7d1 100644
--- a/chromium/components/metrics/child_call_stack_profile_collector.cc
+++ b/chromium/components/metrics/child_call_stack_profile_collector.cc
@@ -15,30 +15,30 @@
namespace metrics {
-ChildCallStackProfileCollector::ProfilesState::ProfilesState() = default;
-ChildCallStackProfileCollector::ProfilesState::ProfilesState(ProfilesState&&) =
+ChildCallStackProfileCollector::ProfileState::ProfileState() = default;
+ChildCallStackProfileCollector::ProfileState::ProfileState(ProfileState&&) =
default;
-ChildCallStackProfileCollector::ProfilesState::ProfilesState(
+ChildCallStackProfileCollector::ProfileState::ProfileState(
const CallStackProfileParams& params,
base::TimeTicks start_timestamp,
- base::StackSamplingProfiler::CallStackProfiles profiles)
+ base::StackSamplingProfiler::CallStackProfile profile)
: params(params),
start_timestamp(start_timestamp),
- profiles(std::move(profiles)) {}
+ profile(std::move(profile)) {}
-ChildCallStackProfileCollector::ProfilesState::~ProfilesState() = default;
+ChildCallStackProfileCollector::ProfileState::~ProfileState() = default;
// Some versions of GCC need this for push_back to work with std::move.
-ChildCallStackProfileCollector::ProfilesState&
-ChildCallStackProfileCollector::ProfilesState::operator=(ProfilesState&&) =
+ChildCallStackProfileCollector::ProfileState&
+ChildCallStackProfileCollector::ProfileState::operator=(ProfileState&&) =
default;
ChildCallStackProfileCollector::ChildCallStackProfileCollector() {}
ChildCallStackProfileCollector::~ChildCallStackProfileCollector() {}
-base::StackSamplingProfiler::CompletedCallback
+CallStackProfileBuilder::CompletedCallback
ChildCallStackProfileCollector::GetProfilerCallback(
const CallStackProfileParams& params,
base::TimeTicks profile_start_time) {
@@ -59,9 +59,9 @@ void ChildCallStackProfileCollector::SetParentProfileCollector(
DCHECK(!parent_collector_);
parent_collector_ = std::move(parent_collector);
if (parent_collector_) {
- for (ProfilesState& state : profiles_) {
+ for (ProfileState& state : profiles_) {
parent_collector_->Collect(state.params, state.start_timestamp,
- std::move(state.profiles));
+ std::move(state.profile));
}
}
profiles_.clear();
@@ -70,16 +70,16 @@ void ChildCallStackProfileCollector::SetParentProfileCollector(
void ChildCallStackProfileCollector::Collect(
const CallStackProfileParams& params,
base::TimeTicks start_timestamp,
- std::vector<CallStackProfile> profiles) {
+ CallStackProfile profile) {
// Impl function is used as it needs to PostTask() to itself on a different
// thread - which only works with a void return value.
- CollectImpl(params, start_timestamp, std::move(profiles));
+ CollectImpl(params, start_timestamp, std::move(profile));
}
void ChildCallStackProfileCollector::CollectImpl(
const CallStackProfileParams& params,
base::TimeTicks start_timestamp,
- std::vector<CallStackProfile> profiles) {
+ CallStackProfile profile) {
base::AutoLock alock(lock_);
if (task_runner_ &&
// The profiler thread does not have a task runner. Attempting to
@@ -91,15 +91,15 @@ void ChildCallStackProfileCollector::CollectImpl(
FROM_HERE, base::BindOnce(&ChildCallStackProfileCollector::CollectImpl,
// This class has lazy instance lifetime.
base::Unretained(this), params,
- start_timestamp, std::move(profiles)));
+ start_timestamp, std::move(profile)));
return;
}
if (parent_collector_) {
- parent_collector_->Collect(params, start_timestamp, std::move(profiles));
+ parent_collector_->Collect(params, start_timestamp, std::move(profile));
} else if (retain_profiles_) {
profiles_.push_back(
- ProfilesState(params, start_timestamp, std::move(profiles)));
+ ProfileState(params, start_timestamp, std::move(profile)));
}
}
diff --git a/chromium/components/metrics/child_call_stack_profile_collector.h b/chromium/components/metrics/child_call_stack_profile_collector.h
index a829f51911a..6e5f331326f 100644
--- a/chromium/components/metrics/child_call_stack_profile_collector.h
+++ b/chromium/components/metrics/child_call_stack_profile_collector.h
@@ -11,6 +11,7 @@
#include "base/memory/ref_counted.h"
#include "base/single_thread_task_runner.h"
#include "base/synchronization/lock.h"
+#include "components/metrics/call_stack_profile_builder.h"
#include "components/metrics/public/interfaces/call_stack_profile_collector.mojom.h"
namespace service_manager {
@@ -41,7 +42,7 @@ namespace metrics {
// g_call_stack_profile_collector = LAZY_INSTANCE_INITIALIZER;
//
// Then, invoke CreateCompletedCallback() to generate the CompletedCallback to
-// pass when creating the StackSamplingProfiler.
+// pass when creating the CallStackProfileBuilder.
//
// When the mojo InterfaceProvider becomes available, provide it via
// SetParentProfileCollector().
@@ -50,11 +51,11 @@ class ChildCallStackProfileCollector {
ChildCallStackProfileCollector();
~ChildCallStackProfileCollector();
- // Get a callback for use with StackSamplingProfiler that provides completed
- // profiles to this object. The callback should be immediately passed to the
- // StackSamplingProfiler, and should not be reused between
- // StackSamplingProfilers. This function may be called on any thread.
- base::StackSamplingProfiler::CompletedCallback GetProfilerCallback(
+ // Get a callback for use with CallStackProfileBuilder that provides the
+ // completed profile to this object. The callback should be immediately passed
+ // to the CallStackProfileBuilder, and should not be reused between
+ // CallStackProfileBuilders. This function may be called on any thread.
+ CallStackProfileBuilder::CompletedCallback GetProfilerCallback(
const CallStackProfileParams& params,
base::TimeTicks profile_start_time);
@@ -67,39 +68,38 @@ class ChildCallStackProfileCollector {
private:
friend class ChildCallStackProfileCollectorTest;
- // Bundles together a set of collected profiles and the collection state for
- // storage, pending availability of the parent mojo interface. |profiles|
+ // Bundles together a collected profile and the collection state for
+ // storage, pending availability of the parent mojo interface. |profile|
// is not const& because it must be passed with std::move.
- struct ProfilesState {
- ProfilesState();
- ProfilesState(ProfilesState&&);
- ProfilesState(
- const CallStackProfileParams& params,
- base::TimeTicks start_timestamp,
- base::StackSamplingProfiler::CallStackProfiles profiles);
- ~ProfilesState();
+ struct ProfileState {
+ ProfileState();
+ ProfileState(ProfileState&&);
+ ProfileState(const CallStackProfileParams& params,
+ base::TimeTicks start_timestamp,
+ base::StackSamplingProfiler::CallStackProfile profile);
+ ~ProfileState();
- ProfilesState& operator=(ProfilesState&&);
+ ProfileState& operator=(ProfileState&&);
CallStackProfileParams params;
base::TimeTicks start_timestamp;
- // The sampled profiles.
- base::StackSamplingProfiler::CallStackProfiles profiles;
+ // The sampled profile.
+ base::StackSamplingProfiler::CallStackProfile profile;
private:
- DISALLOW_COPY_AND_ASSIGN(ProfilesState);
+ DISALLOW_COPY_AND_ASSIGN(ProfileState);
};
using CallStackProfile = base::StackSamplingProfiler::CallStackProfile;
void Collect(const CallStackProfileParams& params,
base::TimeTicks start_timestamp,
- std::vector<CallStackProfile> profiles);
+ CallStackProfile profile);
void CollectImpl(const CallStackProfileParams& params,
base::TimeTicks start_timestamp,
- std::vector<CallStackProfile> profiles);
+ CallStackProfile profile);
// This object may be accessed on any thread, including the profiler
// thread. The expected use case for the object is to be created and have
@@ -107,7 +107,7 @@ class ChildCallStackProfileCollector {
// of PostTask and the like for inter-thread communication.
base::Lock lock_;
- // Whether to retain profiles when the interface is not set. Remains true
+ // Whether to retain the profile when the interface is not set. Remains true
// until the invocation of SetParentProfileCollector(), at which point it is
// false for the rest of the object lifetime.
bool retain_profiles_ = true;
@@ -123,7 +123,7 @@ class ChildCallStackProfileCollector {
// Profiles being cached by this object, pending a parent interface to be
// supplied.
- std::vector<ProfilesState> profiles_;
+ std::vector<ProfileState> profiles_;
DISALLOW_COPY_AND_ASSIGN(ChildCallStackProfileCollector);
};
diff --git a/chromium/components/metrics/child_call_stack_profile_collector_unittest.cc b/chromium/components/metrics/child_call_stack_profile_collector_unittest.cc
index 8bf1c5b7ca8..aa924cb0bc7 100644
--- a/chromium/components/metrics/child_call_stack_profile_collector_unittest.cc
+++ b/chromium/components/metrics/child_call_stack_profile_collector_unittest.cc
@@ -19,11 +19,6 @@
namespace metrics {
-namespace {
-
-
-} // namespace
-
class ChildCallStackProfileCollectorTest : public testing::Test {
protected:
class Receiver : public mojom::CallStackProfileCollector {
@@ -36,14 +31,12 @@ class ChildCallStackProfileCollectorTest : public testing::Test {
void Collect(const CallStackProfileParams& params,
base::TimeTicks start_timestamp,
- std::vector<CallStackProfile> profiles) override {
- this->profiles.push_back(ChildCallStackProfileCollector::ProfilesState(
- params,
- start_timestamp,
- std::move(profiles)));
+ CallStackProfile profile) override {
+ this->profiles.push_back(ChildCallStackProfileCollector::ProfileState(
+ params, start_timestamp, std::move(profile)));
}
- std::vector<ChildCallStackProfileCollector::ProfilesState> profiles;
+ std::vector<ChildCallStackProfileCollector::ProfileState> profiles;
private:
mojo::Binding<mojom::CallStackProfileCollector> binding_;
@@ -54,18 +47,14 @@ class ChildCallStackProfileCollectorTest : public testing::Test {
ChildCallStackProfileCollectorTest()
: receiver_impl_(new Receiver(MakeRequest(&receiver_))) {}
- void CollectEmptyProfiles(
- const CallStackProfileParams& params,
- size_t profile_count) {
- base::StackSamplingProfiler::CallStackProfiles profiles;
- for (size_t i = 0; i < profile_count; ++i)
- profiles.push_back(base::StackSamplingProfiler::CallStackProfile());
+ void CollectEmptyProfile(const CallStackProfileParams& params) {
+ base::StackSamplingProfiler::CallStackProfile profile;
child_collector_.GetProfilerCallback(params, base::TimeTicks::Now())
- .Run(std::move(profiles));
+ .Run(std::move(profile));
}
- const std::vector<ChildCallStackProfileCollector::ProfilesState>&
- profiles() const {
+ const std::vector<ChildCallStackProfileCollector::ProfileState>& profiles()
+ const {
return child_collector_.profiles_;
}
@@ -82,13 +71,11 @@ class ChildCallStackProfileCollectorTest : public testing::Test {
TEST_F(ChildCallStackProfileCollectorTest, InterfaceProvided) {
EXPECT_EQ(0u, profiles().size());
- // Add profiles before providing the interface.
- CollectEmptyProfiles(
- CallStackProfileParams(CallStackProfileParams::BROWSER_PROCESS,
- CallStackProfileParams::MAIN_THREAD,
- CallStackProfileParams::JANKY_TASK,
- CallStackProfileParams::PRESERVE_ORDER),
- 2);
+ // Add a profile before providing the interface.
+ CollectEmptyProfile(CallStackProfileParams(
+ CallStackProfileParams::BROWSER_PROCESS,
+ CallStackProfileParams::MAIN_THREAD, CallStackProfileParams::JANKY_TASK,
+ CallStackProfileParams::PRESERVE_ORDER));
ASSERT_EQ(1u, profiles().size());
EXPECT_EQ(CallStackProfileParams::BROWSER_PROCESS,
profiles()[0].params.process);
@@ -99,7 +86,6 @@ TEST_F(ChildCallStackProfileCollectorTest, InterfaceProvided) {
base::TimeTicks start_timestamp = profiles()[0].start_timestamp;
EXPECT_GE(base::TimeDelta::FromMilliseconds(10),
base::TimeTicks::Now() - start_timestamp);
- EXPECT_EQ(2u, profiles()[0].profiles.size());
// Set the interface. The profiles should be passed to it.
child_collector_.SetParentProfileCollector(std::move(receiver_));
@@ -111,17 +97,13 @@ TEST_F(ChildCallStackProfileCollectorTest, InterfaceProvided) {
EXPECT_EQ(CallStackProfileParams::PRESERVE_ORDER,
receiver_impl_->profiles[0].params.ordering_spec);
EXPECT_EQ(start_timestamp, receiver_impl_->profiles[0].start_timestamp);
- EXPECT_EQ(2u, receiver_impl_->profiles[0].profiles.size());
- // Add profiles after providing the interface. They should also be passed to
- // it.
+ // Add a profile after providing the interface. It should also be passed.
receiver_impl_->profiles.clear();
- CollectEmptyProfiles(
- CallStackProfileParams(CallStackProfileParams::GPU_PROCESS,
- CallStackProfileParams::MAIN_THREAD,
- CallStackProfileParams::THREAD_HUNG,
- CallStackProfileParams::PRESERVE_ORDER),
- 1);
+ CollectEmptyProfile(CallStackProfileParams(
+ CallStackProfileParams::GPU_PROCESS, CallStackProfileParams::MAIN_THREAD,
+ CallStackProfileParams::THREAD_HUNG,
+ CallStackProfileParams::PRESERVE_ORDER));
base::RunLoop().RunUntilIdle();
EXPECT_EQ(0u, profiles().size());
ASSERT_EQ(1u, receiver_impl_->profiles.size());
@@ -136,19 +118,16 @@ TEST_F(ChildCallStackProfileCollectorTest, InterfaceProvided) {
EXPECT_GE(base::TimeDelta::FromMilliseconds(10),
(base::TimeTicks::Now() -
receiver_impl_->profiles[0].start_timestamp));
- EXPECT_EQ(1u, receiver_impl_->profiles[0].profiles.size());
}
TEST_F(ChildCallStackProfileCollectorTest, InterfaceNotProvided) {
EXPECT_EQ(0u, profiles().size());
- // Add profiles before providing a null interface.
- CollectEmptyProfiles(
- CallStackProfileParams(CallStackProfileParams::BROWSER_PROCESS,
- CallStackProfileParams::MAIN_THREAD,
- CallStackProfileParams::JANKY_TASK,
- CallStackProfileParams::PRESERVE_ORDER),
- 2);
+ // Add a profile before providing a null interface.
+ CollectEmptyProfile(CallStackProfileParams(
+ CallStackProfileParams::BROWSER_PROCESS,
+ CallStackProfileParams::MAIN_THREAD, CallStackProfileParams::JANKY_TASK,
+ CallStackProfileParams::PRESERVE_ORDER));
ASSERT_EQ(1u, profiles().size());
EXPECT_EQ(CallStackProfileParams::BROWSER_PROCESS,
profiles()[0].params.process);
@@ -158,21 +137,19 @@ TEST_F(ChildCallStackProfileCollectorTest, InterfaceNotProvided) {
profiles()[0].params.ordering_spec);
EXPECT_GE(base::TimeDelta::FromMilliseconds(10),
base::TimeTicks::Now() - profiles()[0].start_timestamp);
- EXPECT_EQ(2u, profiles()[0].profiles.size());
- // Set the null interface. The profiles should be flushed.
+ // Set the null interface. The profile should be flushed.
child_collector_.SetParentProfileCollector(
mojom::CallStackProfileCollectorPtr());
base::RunLoop().RunUntilIdle();
EXPECT_EQ(0u, profiles().size());
- // Add profiles after providing a null interface. They should also be flushed.
- CollectEmptyProfiles(
- CallStackProfileParams(CallStackProfileParams::GPU_PROCESS,
- CallStackProfileParams::MAIN_THREAD,
- CallStackProfileParams::THREAD_HUNG,
- CallStackProfileParams::PRESERVE_ORDER),
- 1);
+ // Add a profile after providing a null interface. They should also be
+ // flushed.
+ CollectEmptyProfile(CallStackProfileParams(
+ CallStackProfileParams::GPU_PROCESS, CallStackProfileParams::MAIN_THREAD,
+ CallStackProfileParams::THREAD_HUNG,
+ CallStackProfileParams::PRESERVE_ORDER));
EXPECT_EQ(0u, profiles().size());
}
diff --git a/chromium/components/metrics/generate_expired_histograms_array.gni b/chromium/components/metrics/generate_expired_histograms_array.gni
index b211c6676a8..b4522465325 100644
--- a/chromium/components/metrics/generate_expired_histograms_array.gni
+++ b/chromium/components/metrics/generate_expired_histograms_array.gni
@@ -46,7 +46,7 @@ template("generate_expired_histograms_array") {
"-o" + rebase_path(root_gen_dir, root_build_dir),
"-H" + rebase_path(header_filename, root_gen_dir),
"-d" + rebase_path(major_branch_date_filepath, root_build_dir),
- "-m" + rebase_path(milestone_filepath),
+ "-m" + rebase_path(milestone_filepath, root_build_dir),
] + rebase_path(inputs, root_build_dir)
}
}
diff --git a/chromium/components/metrics/gpu/gpu_metrics_provider.cc b/chromium/components/metrics/gpu/gpu_metrics_provider.cc
index 7eacbe710ee..53c15fb7c87 100644
--- a/chromium/components/metrics/gpu/gpu_metrics_provider.cc
+++ b/chromium/components/metrics/gpu/gpu_metrics_provider.cc
@@ -23,12 +23,13 @@ void GPUMetricsProvider::ProvideSystemProfileMetrics(
const gpu::GPUInfo& gpu_info =
content::GpuDataManager::GetInstance()->GetGPUInfo();
+ const gpu::GPUInfo::GPUDevice& active_gpu = gpu_info.active_gpu();
SystemProfileProto::Hardware::Graphics* gpu =
hardware->mutable_gpu();
- gpu->set_vendor_id(gpu_info.gpu.vendor_id);
- gpu->set_device_id(gpu_info.gpu.device_id);
- gpu->set_driver_version(gpu_info.driver_version);
- gpu->set_driver_date(gpu_info.driver_date);
+ gpu->set_vendor_id(active_gpu.vendor_id);
+ gpu->set_device_id(active_gpu.device_id);
+ gpu->set_driver_version(active_gpu.driver_version);
+ gpu->set_driver_date(active_gpu.driver_date);
gpu->set_gl_vendor(gpu_info.gl_vendor);
gpu->set_gl_renderer(gpu_info.gl_renderer);
}
diff --git a/chromium/components/metrics/metrics_log.cc b/chromium/components/metrics/metrics_log.cc
index a99d3c7489c..e7504d351c8 100644
--- a/chromium/components/metrics/metrics_log.cc
+++ b/chromium/components/metrics/metrics_log.cc
@@ -19,6 +19,7 @@
#include "base/metrics/histogram_snapshot_manager.h"
#include "base/metrics/metrics_hashes.h"
#include "base/strings/string_piece.h"
+#include "base/strings/stringprintf.h"
#include "base/sys_info.h"
#include "base/time/time.h"
#include "build/build_config.h"
@@ -170,7 +171,9 @@ void MetricsLog::RecordCoreSystemProfile(MetricsServiceClient* client,
metrics::SystemProfileProto::OS* os = system_profile->mutable_os();
os->set_name(base::SysInfo::OperatingSystemName());
os->set_version(base::SysInfo::OperatingSystemVersion());
-#if defined(OS_ANDROID)
+#if defined(OS_CHROMEOS)
+ os->set_kernel_version(base::SysInfo::KernelVersion());
+#elif defined(OS_ANDROID)
os->set_build_fingerprint(
base::android::BuildInfo::GetInstance()->android_build_fp());
std::string package_name = client->GetAppPackageName();
diff --git a/chromium/components/metrics/metrics_log_unittest.cc b/chromium/components/metrics/metrics_log_unittest.cc
index c4250180a6d..8af49a8cbbc 100644
--- a/chromium/components/metrics/metrics_log_unittest.cc
+++ b/chromium/components/metrics/metrics_log_unittest.cc
@@ -15,6 +15,7 @@
#include "base/metrics/bucket_ranges.h"
#include "base/metrics/sample_vector.h"
#include "base/strings/string_number_conversions.h"
+#include "base/strings/stringprintf.h"
#include "base/sys_info.h"
#include "base/time/time.h"
#include "components/metrics/delegating_provider.h"
@@ -153,7 +154,10 @@ TEST_F(MetricsLogTest, BasicRecord) {
system_profile->mutable_os()->set_name(base::SysInfo::OperatingSystemName());
system_profile->mutable_os()->set_version(
base::SysInfo::OperatingSystemVersion());
-#if defined(OS_ANDROID)
+#if defined(OS_CHROMEOS)
+ system_profile->mutable_os()->set_kernel_version(
+ base::SysInfo::KernelVersion());
+#elif defined(OS_ANDROID)
system_profile->mutable_os()->set_build_fingerprint(
base::android::BuildInfo::GetInstance()->android_build_fp());
system_profile->set_app_package_name("test app");
diff --git a/chromium/components/metrics/metrics_state_manager_unittest.cc b/chromium/components/metrics/metrics_state_manager_unittest.cc
index 3e27e1a2696..0e1f1481c64 100644
--- a/chromium/components/metrics/metrics_state_manager_unittest.cc
+++ b/chromium/components/metrics/metrics_state_manager_unittest.cc
@@ -14,7 +14,7 @@
#include "base/command_line.h"
#include "base/macros.h"
#include "base/strings/string16.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
#include "components/metrics/client_info.h"
#include "components/metrics/metrics_log.h"
#include "components/metrics/metrics_pref_names.h"
diff --git a/chromium/components/metrics/net/net_metrics_log_uploader.cc b/chromium/components/metrics/net/net_metrics_log_uploader.cc
index cbe1f0a0582..addad6b9f1a 100644
--- a/chromium/components/metrics/net/net_metrics_log_uploader.cc
+++ b/chromium/components/metrics/net/net_metrics_log_uploader.cc
@@ -12,6 +12,7 @@
#include "components/encrypted_messages/message_encrypter.h"
#include "components/metrics/metrics_log_uploader.h"
#include "net/base/load_flags.h"
+#include "net/base/url_util.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
#include "net/url_request/url_fetcher.h"
#include "third_party/metrics_proto/reporting_info.pb.h"
@@ -195,8 +196,10 @@ void NetMetricsLogUploader::UploadLogToURL(
service);
current_fetch_->SetRequestContext(request_context_getter_);
std::string reporting_info_string = SerializeReportingInfo(reporting_info);
- // If we are not using HTTPS for this upload, encrypt it.
- if (!url.SchemeIs(url::kHttpsScheme)) {
+ // If we are not using HTTPS for this upload, encrypt it. We do not encrypt
+ // requests to localhost to allow testing with a local collector that doesn't
+ // have decryption enabled.
+ if (!url.SchemeIs(url::kHttpsScheme) && !net::IsLocalhost(url)) {
std::string encrypted_message;
if (!EncryptString(compressed_log_data, &encrypted_message)) {
current_fetch_.reset();
diff --git a/chromium/components/metrics/net/net_metrics_log_uploader_unittest.cc b/chromium/components/metrics/net/net_metrics_log_uploader_unittest.cc
index 7f7747e43e5..76652ec3968 100644
--- a/chromium/components/metrics/net/net_metrics_log_uploader_unittest.cc
+++ b/chromium/components/metrics/net/net_metrics_log_uploader_unittest.cc
@@ -32,11 +32,10 @@ class NetMetricsLogUploaderTest : public testing::Test {
reporting_info);
}
- void CreateUploaderAndUploadToSecureURL() {
+ void CreateUploaderAndUploadToSecureURL(const std::string& url) {
ReportingInfo dummy_reporting_info;
uploader_.reset(new NetMetricsLogUploader(
- nullptr, "https://dummy_secure_server", "dummy_mime",
- MetricsLogUploader::UMA,
+ nullptr, url, "dummy_mime", MetricsLogUploader::UMA,
base::Bind(&NetMetricsLogUploaderTest::DummyOnUploadComplete,
base::Unretained(this))));
uploader_->UploadLog("dummy_data", "dummy_hash", dummy_reporting_info);
@@ -128,7 +127,16 @@ TEST_F(NetMetricsLogUploaderTest, MessageOverHTTPIsEncrypted) {
// message.
TEST_F(NetMetricsLogUploaderTest, MessageOverHTTPSIsNotEncrypted) {
net::TestURLFetcherFactory factory;
- CreateUploaderAndUploadToSecureURL();
+ CreateUploaderAndUploadToSecureURL("https://dummy_secure_server");
+ net::TestURLFetcher* fetcher = factory.GetFetcherByID(0);
+ EXPECT_EQ(fetcher->upload_data(), "dummy_data");
+}
+
+// Test that attempting to upload to localhost over http results in an
+// unencrypted message.
+TEST_F(NetMetricsLogUploaderTest, MessageOverHTTPLocalhostIsNotEncrypted) {
+ net::TestURLFetcherFactory factory;
+ CreateUploaderAndUploadToSecureURL("http://localhost");
net::TestURLFetcher* fetcher = factory.GetFetcherByID(0);
EXPECT_EQ(fetcher->upload_data(), "dummy_data");
}
diff --git a/chromium/components/metrics/net/network_metrics_provider.cc b/chromium/components/metrics/net/network_metrics_provider.cc
index 412f0afbb40..a0cdd391a03 100644
--- a/chromium/components/metrics/net/network_metrics_provider.cc
+++ b/chromium/components/metrics/net/network_metrics_provider.cc
@@ -208,6 +208,8 @@ void NetworkMetricsProvider::ProvideSystemProfileMetrics(
// window, since OnConnectionTypeChanged() ignores transitions to the "none"
// state.
connection_type_ = net::NetworkChangeNotifier::GetConnectionType();
+ if (connection_type_ != net::NetworkChangeNotifier::CONNECTION_UNKNOWN)
+ network_change_notifier_initialized_ = true;
// Reset the "ambiguous" flags, since a new metrics log session has started.
connection_type_is_ambiguous_ = false;
wifi_phy_layer_protocol_is_ambiguous_ = false;
@@ -415,7 +417,7 @@ void NetworkMetricsProvider::WriteWifiAccessPointProto(
void NetworkMetricsProvider::LogAggregatedMetrics() {
DCHECK(thread_checker_.CalledOnValidThread());
base::HistogramBase* error_codes = base::SparseHistogram::FactoryGet(
- "Net.ErrorCodesForMainFrame3",
+ "Net.ErrorCodesForMainFrame4",
base::HistogramBase::kUmaTargetedHistogramFlag);
std::unique_ptr<base::HistogramSamples> samples =
error_codes->SnapshotSamples();
diff --git a/chromium/components/metrics/net/network_metrics_provider.h b/chromium/components/metrics/net/network_metrics_provider.h
index c1a0312efb6..f0f6d0e0334 100644
--- a/chromium/components/metrics/net/network_metrics_provider.h
+++ b/chromium/components/metrics/net/network_metrics_provider.h
@@ -125,7 +125,7 @@ class NetworkMetricsProvider
// Helper object for retrieving connected wifi access point information.
std::unique_ptr<WifiAccessPointInfoProvider> wifi_access_point_info_provider_;
- // These metrics track histogram totals for the Net.ErrorCodesForMainFrame3
+ // These metrics track histogram totals for the Net.ErrorCodesForMainFrame4
// histogram. They are used to compute deltas at upload time.
base::HistogramBase::Count total_aborts_;
base::HistogramBase::Count total_codes_;
diff --git a/chromium/components/metrics/public/cpp/OWNERS b/chromium/components/metrics/public/cpp/OWNERS
index 154435234ea..2c44a463856 100644
--- a/chromium/components/metrics/public/cpp/OWNERS
+++ b/chromium/components/metrics/public/cpp/OWNERS
@@ -2,3 +2,5 @@ per-file *.mojom=set noparent
per-file *.mojom=file://ipc/SECURITY_OWNERS
per-file *_struct_traits*.*=set noparent
per-file *_struct_traits*.*=file://ipc/SECURITY_OWNERS
+per-file *.typemap=set noparent
+per-file *.typemap=file://ipc/SECURITY_OWNERS
diff --git a/chromium/components/metrics/public/cpp/call_stack_profile.typemap b/chromium/components/metrics/public/cpp/call_stack_profile.typemap
index 611148c8255..aa8456507d3 100644
--- a/chromium/components/metrics/public/cpp/call_stack_profile.typemap
+++ b/chromium/components/metrics/public/cpp/call_stack_profile.typemap
@@ -12,7 +12,7 @@ traits_headers =
[ "//components/metrics/public/cpp/call_stack_profile_struct_traits.h" ]
deps = [
"//base",
- "//components/metrics:call_stack_profile_params",
+ "//components/metrics:call_stack_profile",
]
type_mappings = [
"metrics.mojom.CallStackModule=base::StackSamplingProfiler::Module",
diff --git a/chromium/components/metrics/public/cpp/call_stack_profile_struct_traits.h b/chromium/components/metrics/public/cpp/call_stack_profile_struct_traits.h
index 98aae66fd70..b062a5a0497 100644
--- a/chromium/components/metrics/public/cpp/call_stack_profile_struct_traits.h
+++ b/chromium/components/metrics/public/cpp/call_stack_profile_struct_traits.h
@@ -56,17 +56,16 @@ struct StructTraits<metrics::mojom::CallStackFrameDataView,
}
static uint64_t module_index(
const base::StackSamplingProfiler::Frame& frame) {
- return frame.module_index ==
- base::StackSamplingProfiler::Frame::kUnknownModuleIndex ?
- static_cast<uint64_t>(-1) :
- frame.module_index;
+ return frame.module_index == base::kUnknownModuleIndex
+ ? static_cast<uint64_t>(-1)
+ : frame.module_index;
}
static bool Read(metrics::mojom::CallStackFrameDataView data,
base::StackSamplingProfiler::Frame* out) {
- size_t module_index = data.module_index() == static_cast<uint64_t>(-1) ?
- base::StackSamplingProfiler::Frame::kUnknownModuleIndex :
- data.module_index();
+ size_t module_index = data.module_index() == static_cast<uint64_t>(-1)
+ ? base::kUnknownModuleIndex
+ : data.module_index();
// We can't know whether the module_index field is valid at this point since
// we don't have access to the number of modules here. This will be checked
@@ -128,8 +127,7 @@ struct StructTraits<metrics::mojom::CallStackProfileDataView,
for (const base::StackSamplingProfiler::Sample& sample : samples) {
for (const base::StackSamplingProfiler::Frame& frame : sample.frames) {
if (frame.module_index >= module_count &&
- frame.module_index !=
- base::StackSamplingProfiler::Frame::kUnknownModuleIndex)
+ frame.module_index != base::kUnknownModuleIndex)
return false;
}
}
diff --git a/chromium/components/metrics/public/cpp/call_stack_profile_struct_traits_unittest.cc b/chromium/components/metrics/public/cpp/call_stack_profile_struct_traits_unittest.cc
index 7bdb4dbb085..b0d2bf0288b 100644
--- a/chromium/components/metrics/public/cpp/call_stack_profile_struct_traits_unittest.cc
+++ b/chromium/components/metrics/public/cpp/call_stack_profile_struct_traits_unittest.cc
@@ -151,20 +151,20 @@ TEST_F(CallStackProfileStructTraitsTest, Frame) {
using Frame = base::StackSamplingProfiler::Frame;
const Frame serialize_cases[] = {
- // Null instruction pointer.
- Frame(0x0, 10),
- // Non-null instruction pointer.
- Frame(0x10, 10),
- // Instruction pointer with a bit set beyond 32 bits, when built for x64.
- Frame(1ULL << (sizeof(uintptr_t) * 8) * 3 / 4, 10),
- // Zero module index.
- Frame(0xabcd, 0),
- // Non-zero module index.
- Frame(0xabcd, 1),
- // Non-zero module index.
- Frame(0xabcd, 10),
- // Unknown module index.
- Frame(0xabcd, Frame::kUnknownModuleIndex),
+ // Null instruction pointer.
+ Frame(0x0, 10),
+ // Non-null instruction pointer.
+ Frame(0x10, 10),
+ // Instruction pointer with a bit set beyond 32 bits, when built for x64.
+ Frame(1ULL << (sizeof(uintptr_t) * 8) * 3 / 4, 10),
+ // Zero module index.
+ Frame(0xabcd, 0),
+ // Non-zero module index.
+ Frame(0xabcd, 1),
+ // Non-zero module index.
+ Frame(0xabcd, 10),
+ // Unknown module index.
+ Frame(0xabcd, base::kUnknownModuleIndex),
};
for (const Frame& input : serialize_cases) {
@@ -179,10 +179,11 @@ TEST_F(CallStackProfileStructTraitsTest, Frame) {
// Checks serialization/deserialization of Profile fields, including validation
// of the Frame module_index field.
TEST_F(CallStackProfileStructTraitsTest, Profile) {
- using Module = base::StackSamplingProfiler::Module;
- using Frame = base::StackSamplingProfiler::Frame;
- using Sample = base::StackSamplingProfiler::Sample;
- using Profile = base::StackSamplingProfiler::CallStackProfile;
+ using base::StackSamplingProfiler;
+ using Module = StackSamplingProfiler::Module;
+ using Frame = StackSamplingProfiler::Frame;
+ using Sample = StackSamplingProfiler::Sample;
+ using Profile = StackSamplingProfiler::CallStackProfile;
struct SerializeCase {
Profile profile;
@@ -190,60 +191,49 @@ TEST_F(CallStackProfileStructTraitsTest, Profile) {
};
const SerializeCase serialize_cases[] = {
- // Empty modules and samples.
- {
- CreateProfile(std::vector<Module>(), std::vector<Sample>(),
- base::TimeDelta::FromSeconds(1),
- base::TimeDelta::FromSeconds(2)),
- true
- },
- // Non-empty modules and empty samples.
- {
- CreateProfile({ Module(0x4000, "a", base::FilePath()) },
- std::vector<Sample>(),
- base::TimeDelta::FromSeconds(1),
- base::TimeDelta::FromSeconds(2)),
- true
- },
- // Valid values for modules and samples.
- {
- CreateProfile({
- Module(0x4000, "a", base::FilePath()),
- Module(0x4100, "b", base::FilePath()),
- },
- {
- Sample({
- Frame(0x4010, 0),
- Frame(0x4110, 1),
- Frame(0x4110, Frame::kUnknownModuleIndex),
- }),
- },
- base::TimeDelta::FromSeconds(1),
- base::TimeDelta::FromSeconds(2)),
- true
- },
- // Valid values for modules, but an out of range module index in the second
- // sample.
- {
- CreateProfile({
- Module(0x4000, "a", base::FilePath()),
- Module(0x4100, "b", base::FilePath()),
- },
- {
- Sample({
- Frame(0x4010, 0),
- Frame(0x4110, 1),
- Frame(0x4110, Frame::kUnknownModuleIndex),
- }),
- Sample({
- Frame(0x4010, 0),
- Frame(0x4110, 2),
- }),
- },
- base::TimeDelta::FromSeconds(1),
- base::TimeDelta::FromSeconds(2)),
- false
- },
+ // Empty modules and samples.
+ {CreateProfile(std::vector<Module>(), std::vector<Sample>(),
+ base::TimeDelta::FromSeconds(1),
+ base::TimeDelta::FromSeconds(2)),
+ true},
+ // Non-empty modules and empty samples.
+ {CreateProfile({Module(0x4000, "a", base::FilePath())},
+ std::vector<Sample>(), base::TimeDelta::FromSeconds(1),
+ base::TimeDelta::FromSeconds(2)),
+ true},
+ // Valid values for modules and samples.
+ {CreateProfile(
+ {
+ Module(0x4000, "a", base::FilePath()),
+ Module(0x4100, "b", base::FilePath()),
+ },
+ {
+ Sample({
+ Frame(0x4010, 0), Frame(0x4110, 1),
+ Frame(0x4110, base::kUnknownModuleIndex),
+ }),
+ },
+ base::TimeDelta::FromSeconds(1), base::TimeDelta::FromSeconds(2)),
+ true},
+ // Valid values for modules, but an out of range module index in the
+ // second
+ // sample.
+ {CreateProfile(
+ {
+ Module(0x4000, "a", base::FilePath()),
+ Module(0x4100, "b", base::FilePath()),
+ },
+ {
+ Sample({
+ Frame(0x4010, 0), Frame(0x4110, 1),
+ Frame(0x4110, base::kUnknownModuleIndex),
+ }),
+ Sample({
+ Frame(0x4010, 0), Frame(0x4110, 2),
+ }),
+ },
+ base::TimeDelta::FromSeconds(1), base::TimeDelta::FromSeconds(2)),
+ false},
};
for (const SerializeCase& input : serialize_cases) {
diff --git a/chromium/components/metrics/public/interfaces/call_stack_profile_collector.mojom b/chromium/components/metrics/public/interfaces/call_stack_profile_collector.mojom
index d265d606e89..8f0031db654 100644
--- a/chromium/components/metrics/public/interfaces/call_stack_profile_collector.mojom
+++ b/chromium/components/metrics/public/interfaces/call_stack_profile_collector.mojom
@@ -74,5 +74,5 @@ struct CallStackProfileParams {
interface CallStackProfileCollector {
Collect(CallStackProfileParams params,
mojo_base.mojom.TimeTicks start_timestamp,
- array<CallStackProfile> profiles);
+ CallStackProfile profile);
};
diff --git a/chromium/components/metrics/single_sample_metrics_factory_impl_unittest.cc b/chromium/components/metrics/single_sample_metrics_factory_impl_unittest.cc
index f9fbbba6c44..cec7c869c12 100644
--- a/chromium/components/metrics/single_sample_metrics_factory_impl_unittest.cc
+++ b/chromium/components/metrics/single_sample_metrics_factory_impl_unittest.cc
@@ -8,7 +8,7 @@
#include "base/metrics/dummy_histogram.h"
#include "base/run_loop.h"
#include "base/test/gtest_util.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
#include "base/threading/thread.h"
#include "components/metrics/single_sample_metrics.h"
#include "testing/gtest/include/gtest/gtest.h"
diff --git a/chromium/components/metrics/stability_metrics_helper.cc b/chromium/components/metrics/stability_metrics_helper.cc
index 375f75c4368..517fc71fc86 100644
--- a/chromium/components/metrics/stability_metrics_helper.cc
+++ b/chromium/components/metrics/stability_metrics_helper.cc
@@ -17,6 +17,7 @@
#include "components/metrics/metrics_pref_names.h"
#include "components/prefs/pref_registry_simple.h"
#include "components/prefs/pref_service.h"
+#include "components/variations/hashing.h"
#include "extensions/buildflags/buildflags.h"
#include "third_party/metrics_proto/system_profile.pb.h"
@@ -188,6 +189,23 @@ void StabilityMetricsHelper::IncreaseRendererCrashCount() {
IncrementPrefValue(prefs::kStabilityRendererCrashCount);
}
+void StabilityMetricsHelper::BrowserUtilityProcessLaunched(
+ const std::string& metrics_name) {
+ uint32_t hash = variations::HashName(metrics_name);
+ base::UmaHistogramSparse("ChildProcess.Launched.UtilityProcessHash", hash);
+}
+
+void StabilityMetricsHelper::BrowserUtilityProcessCrashed(
+ const std::string& metrics_name,
+ int exit_code) {
+ // TODO(wfh): there doesn't appear to be a good way to log these exit_codes
+ // without adding something into the stability proto, so for now only log the
+ // crash and if the numbers are high enough, logging exit codes can be added
+ // later.
+ uint32_t hash = variations::HashName(metrics_name);
+ base::UmaHistogramSparse("ChildProcess.Crashed.UtilityProcessHash", hash);
+}
+
void StabilityMetricsHelper::BrowserChildProcessCrashed() {
IncrementPrefValue(prefs::kStabilityChildProcessCrashCount);
}
diff --git a/chromium/components/metrics/stability_metrics_helper.h b/chromium/components/metrics/stability_metrics_helper.h
index ddf4d50c597..5a22882af4b 100644
--- a/chromium/components/metrics/stability_metrics_helper.h
+++ b/chromium/components/metrics/stability_metrics_helper.h
@@ -30,6 +30,13 @@ class StabilityMetricsHelper {
// Clears the gathered stability metrics.
void ClearSavedStabilityMetrics();
+ // Records a utility process launch with name |metrics_name|.
+ void BrowserUtilityProcessLaunched(const std::string& metrics_name);
+
+ // Records a utility process crash with name |metrics_name|.
+ void BrowserUtilityProcessCrashed(const std::string& metrics_name,
+ int exit_code);
+
// Records a browser child process crash.
void BrowserChildProcessCrashed();
diff --git a/chromium/components/metrics/stability_metrics_helper_unittest.cc b/chromium/components/metrics/stability_metrics_helper_unittest.cc
index bcaa2c1e017..66fc041db09 100644
--- a/chromium/components/metrics/stability_metrics_helper_unittest.cc
+++ b/chromium/components/metrics/stability_metrics_helper_unittest.cc
@@ -7,7 +7,7 @@
#include <memory>
#include "base/macros.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
#include "build/build_config.h"
#include "components/prefs/pref_service.h"
#include "components/prefs/scoped_user_pref_update.h"
diff --git a/chromium/components/metrics/stability_metrics_provider_unittest.cc b/chromium/components/metrics/stability_metrics_provider_unittest.cc
index 3a188ec3f83..e0ba0ce9ba7 100644
--- a/chromium/components/metrics/stability_metrics_provider_unittest.cc
+++ b/chromium/components/metrics/stability_metrics_provider_unittest.cc
@@ -4,7 +4,7 @@
#include "components/metrics/stability_metrics_provider.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
#include "build/build_config.h"
#include "components/prefs/testing_pref_service.h"
#include "testing/gtest/include/gtest/gtest.h"