| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "components/metrics/call_stack_profile_metrics_provider.h" | 5 #include "components/metrics/call_stack_profile_metrics_provider.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 | 9 |
| 10 #include <utility> | 10 #include <utility> |
| (...skipping 23 matching lines...) Expand all Loading... |
| 34 uint64_t name_md5; | 34 uint64_t name_md5; |
| 35 uint64_t base_address; | 35 uint64_t base_address; |
| 36 }; | 36 }; |
| 37 | 37 |
| 38 struct ExpectedProtoEntry { | 38 struct ExpectedProtoEntry { |
| 39 int32_t module_index; | 39 int32_t module_index; |
| 40 uint64_t address; | 40 uint64_t address; |
| 41 }; | 41 }; |
| 42 | 42 |
| 43 struct ExpectedProtoSample { | 43 struct ExpectedProtoSample { |
| 44 uint32_t process_phases; // Bit-field of expected phases. | 44 uint32_t process_milestones; // Bit-field of expected milestones. |
| 45 const ExpectedProtoEntry* entries; | 45 const ExpectedProtoEntry* entries; |
| 46 int entry_count; | 46 int entry_count; |
| 47 int64_t entry_repeats; | 47 int64_t entry_repeats; |
| 48 }; | 48 }; |
| 49 | 49 |
| 50 struct ExpectedProtoProfile { | 50 struct ExpectedProtoProfile { |
| 51 int32_t duration_ms; | 51 int32_t duration_ms; |
| 52 int32_t period_ms; | 52 int32_t period_ms; |
| 53 const ExpectedProtoModule* modules; | 53 const ExpectedProtoModule* modules; |
| 54 int module_count; | 54 int module_count; |
| 55 const ExpectedProtoSample* samples; | 55 const ExpectedProtoSample* samples; |
| 56 int sample_count; | 56 int sample_count; |
| 57 }; | 57 }; |
| 58 | 58 |
| 59 class ProfilesFactory { | 59 class ProfilesFactory { |
| 60 public: | 60 public: |
| 61 ProfilesFactory(){}; | 61 ProfilesFactory(){}; |
| 62 ~ProfilesFactory(){}; | 62 ~ProfilesFactory(){}; |
| 63 | 63 |
| 64 ProfilesFactory& AddPhase(int phase); | 64 ProfilesFactory& AddMilestone(int milestone); |
| 65 ProfilesFactory& NewProfile(int duration_ms, int interval_ms); | 65 ProfilesFactory& NewProfile(int duration_ms, int interval_ms); |
| 66 ProfilesFactory& NewSample(); | 66 ProfilesFactory& NewSample(); |
| 67 ProfilesFactory& AddFrame(size_t module, uintptr_t offset); | 67 ProfilesFactory& AddFrame(size_t module, uintptr_t offset); |
| 68 ProfilesFactory& DefineModule(const char* name, | 68 ProfilesFactory& DefineModule(const char* name, |
| 69 const base::FilePath& path, | 69 const base::FilePath& path, |
| 70 uintptr_t base); | 70 uintptr_t base); |
| 71 | 71 |
| 72 Profiles Build(); | 72 Profiles Build(); |
| 73 | 73 |
| 74 private: | 74 private: |
| 75 Profiles profiles_; | 75 Profiles profiles_; |
| 76 uint32_t process_phases_ = 0; | 76 uint32_t process_milestones_ = 0; |
| 77 | 77 |
| 78 DISALLOW_COPY_AND_ASSIGN(ProfilesFactory); | 78 DISALLOW_COPY_AND_ASSIGN(ProfilesFactory); |
| 79 }; | 79 }; |
| 80 | 80 |
| 81 ProfilesFactory& ProfilesFactory::AddPhase(int phase) { | 81 ProfilesFactory& ProfilesFactory::AddMilestone(int milestone) { |
| 82 process_phases_ |= 1 << phase; | 82 process_milestones_ |= 1 << milestone; |
| 83 return *this; | 83 return *this; |
| 84 } | 84 } |
| 85 | 85 |
| 86 ProfilesFactory& ProfilesFactory::NewProfile(int duration_ms, int interval_ms) { | 86 ProfilesFactory& ProfilesFactory::NewProfile(int duration_ms, int interval_ms) { |
| 87 profiles_.push_back(Profile()); | 87 profiles_.push_back(Profile()); |
| 88 Profile* profile = &profiles_.back(); | 88 Profile* profile = &profiles_.back(); |
| 89 profile->profile_duration = base::TimeDelta::FromMilliseconds(duration_ms); | 89 profile->profile_duration = base::TimeDelta::FromMilliseconds(duration_ms); |
| 90 profile->sampling_period = base::TimeDelta::FromMilliseconds(interval_ms); | 90 profile->sampling_period = base::TimeDelta::FromMilliseconds(interval_ms); |
| 91 return *this; | 91 return *this; |
| 92 } | 92 } |
| 93 | 93 |
| 94 ProfilesFactory& ProfilesFactory::NewSample() { | 94 ProfilesFactory& ProfilesFactory::NewSample() { |
| 95 profiles_.back().samples.push_back(Sample()); | 95 profiles_.back().samples.push_back(Sample()); |
| 96 profiles_.back().samples.back().process_phases = process_phases_; | 96 profiles_.back().samples.back().process_milestones = process_milestones_; |
| 97 return *this; | 97 return *this; |
| 98 } | 98 } |
| 99 | 99 |
| 100 ProfilesFactory& ProfilesFactory::AddFrame(size_t module, uintptr_t offset) { | 100 ProfilesFactory& ProfilesFactory::AddFrame(size_t module, uintptr_t offset) { |
| 101 profiles_.back().samples.back().frames.push_back(Frame(offset, module)); | 101 profiles_.back().samples.back().frames.push_back(Frame(offset, module)); |
| 102 return *this; | 102 return *this; |
| 103 } | 103 } |
| 104 | 104 |
| 105 ProfilesFactory& ProfilesFactory::DefineModule(const char* name, | 105 ProfilesFactory& ProfilesFactory::DefineModule(const char* name, |
| 106 const base::FilePath& path, | 106 const base::FilePath& path, |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 174 EXPECT_EQ(expected.modules[m].build_id, module_id.build_id()); | 174 EXPECT_EQ(expected.modules[m].build_id, module_id.build_id()); |
| 175 ASSERT_TRUE(module_id.has_name_md5_prefix()); | 175 ASSERT_TRUE(module_id.has_name_md5_prefix()); |
| 176 EXPECT_EQ(expected.modules[m].name_md5, module_id.name_md5_prefix()); | 176 EXPECT_EQ(expected.modules[m].name_md5, module_id.name_md5_prefix()); |
| 177 } | 177 } |
| 178 | 178 |
| 179 ASSERT_EQ(expected.sample_count, stack.sample().size()); | 179 ASSERT_EQ(expected.sample_count, stack.sample().size()); |
| 180 for (int s = 0; s < expected.sample_count; ++s) { | 180 for (int s = 0; s < expected.sample_count; ++s) { |
| 181 SCOPED_TRACE("sample " + base::IntToString(s)); | 181 SCOPED_TRACE("sample " + base::IntToString(s)); |
| 182 const CallStackProfile::Sample& proto_sample = stack.sample().Get(s); | 182 const CallStackProfile::Sample& proto_sample = stack.sample().Get(s); |
| 183 | 183 |
| 184 uint32_t process_phases = 0; | 184 uint32_t process_milestones = 0; |
| 185 for (int i = 0; i < proto_sample.process_phase().size(); ++i) | 185 for (int i = 0; i < proto_sample.process_phase().size(); ++i) |
| 186 process_phases |= 1U << proto_sample.process_phase().Get(i); | 186 process_milestones |= 1U << proto_sample.process_phase().Get(i); |
| 187 EXPECT_EQ(expected.samples[s].process_phases, process_phases); | 187 EXPECT_EQ(expected.samples[s].process_milestones, process_milestones); |
| 188 | 188 |
| 189 ASSERT_EQ(expected.samples[s].entry_count, proto_sample.entry().size()); | 189 ASSERT_EQ(expected.samples[s].entry_count, proto_sample.entry().size()); |
| 190 ASSERT_TRUE(proto_sample.has_count()); | 190 ASSERT_TRUE(proto_sample.has_count()); |
| 191 EXPECT_EQ(expected.samples[s].entry_repeats, proto_sample.count()); | 191 EXPECT_EQ(expected.samples[s].entry_repeats, proto_sample.count()); |
| 192 for (int e = 0; e < expected.samples[s].entry_count; ++e) { | 192 for (int e = 0; e < expected.samples[s].entry_count; ++e) { |
| 193 SCOPED_TRACE("entry " + base::SizeTToString(e)); | 193 SCOPED_TRACE("entry " + base::SizeTToString(e)); |
| 194 const CallStackProfile::Entry& entry = proto_sample.entry().Get(e); | 194 const CallStackProfile::Entry& entry = proto_sample.entry().Get(e); |
| 195 if (expected.samples[s].entries[e].module_index >= 0) { | 195 if (expected.samples[s].entries[e].module_index >= 0) { |
| 196 ASSERT_TRUE(entry.has_module_id_index()); | 196 ASSERT_TRUE(entry.has_module_id_index()); |
| 197 EXPECT_EQ(expected.samples[s].entries[e].module_index, | 197 EXPECT_EQ(expected.samples[s].entries[e].module_index, |
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 372 base::FilePath module_path(L"c:\\some\\path\\to\\chrome.exe"); | 372 base::FilePath module_path(L"c:\\some\\path\\to\\chrome.exe"); |
| 373 #else | 373 #else |
| 374 uint64_t module_md5 = 0x554838A8451AC36CULL; | 374 uint64_t module_md5 = 0x554838A8451AC36CULL; |
| 375 base::FilePath module_path("/some/path/to/chrome"); | 375 base::FilePath module_path("/some/path/to/chrome"); |
| 376 #endif | 376 #endif |
| 377 | 377 |
| 378 Profiles profiles = ProfilesFactory() | 378 Profiles profiles = ProfilesFactory() |
| 379 .NewProfile(100, 10) | 379 .NewProfile(100, 10) |
| 380 .DefineModule(module_name, module_path, module_base_address) | 380 .DefineModule(module_name, module_path, module_base_address) |
| 381 | 381 |
| 382 .AddPhase(0) | 382 .AddMilestone(0) |
| 383 .NewSample() | 383 .NewSample() |
| 384 .AddFrame(0, module_base_address + 0x10) | 384 .AddFrame(0, module_base_address + 0x10) |
| 385 .NewSample() | 385 .NewSample() |
| 386 .AddFrame(0, module_base_address + 0x20) | 386 .AddFrame(0, module_base_address + 0x20) |
| 387 .NewSample() | 387 .NewSample() |
| 388 .AddFrame(0, module_base_address + 0x10) | 388 .AddFrame(0, module_base_address + 0x10) |
| 389 .NewSample() | 389 .NewSample() |
| 390 .AddFrame(0, module_base_address + 0x10) | 390 .AddFrame(0, module_base_address + 0x10) |
| 391 | 391 |
| 392 .AddPhase(1) | 392 .AddMilestone(1) |
| 393 .NewSample() | 393 .NewSample() |
| 394 .AddFrame(0, module_base_address + 0x10) | 394 .AddFrame(0, module_base_address + 0x10) |
| 395 .NewSample() | 395 .NewSample() |
| 396 .AddFrame(0, module_base_address + 0x20) | 396 .AddFrame(0, module_base_address + 0x20) |
| 397 .NewSample() | 397 .NewSample() |
| 398 .AddFrame(0, module_base_address + 0x10) | 398 .AddFrame(0, module_base_address + 0x10) |
| 399 .NewSample() | 399 .NewSample() |
| 400 .AddFrame(0, module_base_address + 0x10) | 400 .AddFrame(0, module_base_address + 0x10) |
| 401 | 401 |
| 402 .Build(); | 402 .Build(); |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 457 base::FilePath module_path(L"c:\\some\\path\\to\\chrome.exe"); | 457 base::FilePath module_path(L"c:\\some\\path\\to\\chrome.exe"); |
| 458 #else | 458 #else |
| 459 uint64_t module_md5 = 0x554838A8451AC36CULL; | 459 uint64_t module_md5 = 0x554838A8451AC36CULL; |
| 460 base::FilePath module_path("/some/path/to/chrome"); | 460 base::FilePath module_path("/some/path/to/chrome"); |
| 461 #endif | 461 #endif |
| 462 | 462 |
| 463 Profiles profiles = ProfilesFactory() | 463 Profiles profiles = ProfilesFactory() |
| 464 .NewProfile(100, 10) | 464 .NewProfile(100, 10) |
| 465 .DefineModule(module_name, module_path, module_base_address) | 465 .DefineModule(module_name, module_path, module_base_address) |
| 466 | 466 |
| 467 .AddPhase(0) | 467 .AddMilestone(0) |
| 468 .NewSample() | 468 .NewSample() |
| 469 .AddFrame(0, module_base_address + 0x10) | 469 .AddFrame(0, module_base_address + 0x10) |
| 470 .NewSample() | 470 .NewSample() |
| 471 .AddFrame(0, module_base_address + 0x20) | 471 .AddFrame(0, module_base_address + 0x20) |
| 472 .NewSample() | 472 .NewSample() |
| 473 .AddFrame(0, module_base_address + 0x10) | 473 .AddFrame(0, module_base_address + 0x10) |
| 474 .NewSample() | 474 .NewSample() |
| 475 .AddFrame(0, module_base_address + 0x10) | 475 .AddFrame(0, module_base_address + 0x10) |
| 476 | 476 |
| 477 .AddPhase(1) | 477 .AddMilestone(1) |
| 478 .NewSample() | 478 .NewSample() |
| 479 .AddFrame(0, module_base_address + 0x10) | 479 .AddFrame(0, module_base_address + 0x10) |
| 480 .NewSample() | 480 .NewSample() |
| 481 .AddFrame(0, module_base_address + 0x20) | 481 .AddFrame(0, module_base_address + 0x20) |
| 482 .NewSample() | 482 .NewSample() |
| 483 .AddFrame(0, module_base_address + 0x10) | 483 .AddFrame(0, module_base_address + 0x10) |
| 484 .NewSample() | 484 .NewSample() |
| 485 .AddFrame(0, module_base_address + 0x10) | 485 .AddFrame(0, module_base_address + 0x10) |
| 486 | 486 |
| 487 .Build(); | 487 .Build(); |
| (...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 737 .AddFrame(Frame::kUnknownModuleIndex, 0x1234) | 737 .AddFrame(Frame::kUnknownModuleIndex, 0x1234) |
| 738 .Build(); | 738 .Build(); |
| 739 callback.Run(std::move(profiles)); | 739 callback.Run(std::move(profiles)); |
| 740 ChromeUserMetricsExtension uma_proto; | 740 ChromeUserMetricsExtension uma_proto; |
| 741 provider.ProvideGeneralMetrics(&uma_proto); | 741 provider.ProvideGeneralMetrics(&uma_proto); |
| 742 | 742 |
| 743 EXPECT_EQ(0, uma_proto.sampled_profile_size()); | 743 EXPECT_EQ(0, uma_proto.sampled_profile_size()); |
| 744 } | 744 } |
| 745 | 745 |
| 746 } // namespace metrics | 746 } // namespace metrics |
| OLD | NEW |