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> |
| 8 #include <stdint.h> |
| 9 |
| 10 #include "base/macros.h" |
7 #include "base/metrics/field_trial.h" | 11 #include "base/metrics/field_trial.h" |
8 #include "base/profiler/stack_sampling_profiler.h" | 12 #include "base/profiler/stack_sampling_profiler.h" |
9 #include "base/run_loop.h" | 13 #include "base/run_loop.h" |
10 #include "base/strings/string_number_conversions.h" | 14 #include "base/strings/string_number_conversions.h" |
| 15 #include "build/build_config.h" |
11 #include "components/metrics/proto/chrome_user_metrics_extension.pb.h" | 16 #include "components/metrics/proto/chrome_user_metrics_extension.pb.h" |
12 #include "components/variations/entropy_provider.h" | 17 #include "components/variations/entropy_provider.h" |
13 #include "testing/gtest/include/gtest/gtest.h" | 18 #include "testing/gtest/include/gtest/gtest.h" |
14 | 19 |
15 using base::StackSamplingProfiler; | 20 using base::StackSamplingProfiler; |
16 using Frame = StackSamplingProfiler::Frame; | 21 using Frame = StackSamplingProfiler::Frame; |
17 using Module = StackSamplingProfiler::Module; | 22 using Module = StackSamplingProfiler::Module; |
18 using Profile = StackSamplingProfiler::CallStackProfile; | 23 using Profile = StackSamplingProfiler::CallStackProfile; |
19 using Profiles = StackSamplingProfiler::CallStackProfiles; | 24 using Profiles = StackSamplingProfiler::CallStackProfiles; |
20 using Sample = StackSamplingProfiler::Sample; | 25 using Sample = StackSamplingProfiler::Sample; |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
107 | 112 |
108 // Values for Windows generated with: | 113 // Values for Windows generated with: |
109 // perl -MDigest::MD5=md5 -MEncode=encode | 114 // perl -MDigest::MD5=md5 -MEncode=encode |
110 // -e 'for(@ARGV){printf "%x\n", unpack "Q>", md5 encode "UTF-16LE", $_}' | 115 // -e 'for(@ARGV){printf "%x\n", unpack "Q>", md5 encode "UTF-16LE", $_}' |
111 // chrome.exe third_party.dll third_party2.dll | 116 // chrome.exe third_party.dll third_party2.dll |
112 // | 117 // |
113 // Values for Linux generated with: | 118 // Values for Linux generated with: |
114 // perl -MDigest::MD5=md5 | 119 // perl -MDigest::MD5=md5 |
115 // -e 'for(@ARGV){printf "%x\n", unpack "Q>", md5 $_}' | 120 // -e 'for(@ARGV){printf "%x\n", unpack "Q>", md5 $_}' |
116 // chrome third_party.so third_party2.so | 121 // chrome third_party.so third_party2.so |
117 const uint64 profile_expected_name_md5_prefixes[][2] = { | 122 const uint64_t profile_expected_name_md5_prefixes[][2] = { |
118 { | 123 { |
119 #if defined(OS_WIN) | 124 #if defined(OS_WIN) |
120 0x46c3e4166659ac02ULL, | 125 0x46c3e4166659ac02ULL, 0x7e2b8bfddeae1abaULL |
121 0x7e2b8bfddeae1abaULL | |
122 #else | 126 #else |
123 0x554838a8451ac36cUL, | 127 0x554838a8451ac36cUL, 0x843661148659c9f8UL |
124 0x843661148659c9f8UL | |
125 #endif | 128 #endif |
126 }, | 129 }, |
127 { | 130 { |
128 #if defined(OS_WIN) | 131 #if defined(OS_WIN) |
129 0x87b66f4573a4d5caULL, | 132 0x87b66f4573a4d5caULL, 0x46c3e4166659ac02ULL |
130 0x46c3e4166659ac02ULL | |
131 #else | 133 #else |
132 0xb4647e539fa6ec9eUL, | 134 0xb4647e539fa6ec9eUL, 0x554838a8451ac36cUL |
133 0x554838a8451ac36cUL | |
134 #endif | 135 #endif |
135 } | 136 }}; |
136 }; | |
137 | 137 |
138 // Represents two stack samples for each of two profiles, where each stack | 138 // Represents two stack samples for each of two profiles, where each stack |
139 // contains three frames. Each frame contains an instruction pointer and a | 139 // contains three frames. Each frame contains an instruction pointer and a |
140 // module index corresponding to the module for the profile in | 140 // module index corresponding to the module for the profile in |
141 // profile_modules. | 141 // profile_modules. |
142 // | 142 // |
143 // So, the first stack sample below has its top frame in module 0 at an offset | 143 // So, the first stack sample below has its top frame in module 0 at an offset |
144 // of 0x10 from the module's base address, the next-to-top frame in module 1 | 144 // of 0x10 from the module's base address, the next-to-top frame in module 1 |
145 // at an offset of 0x20 from the module's base address, and the bottom frame | 145 // at an offset of 0x20 from the module's base address, and the bottom frame |
146 // in module 0 at an offset of 0x30 from the module's base address | 146 // in module 0 at an offset of 0x30 from the module's base address |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
231 EXPECT_EQ(1u, proto_sample.count()); | 231 EXPECT_EQ(1u, proto_sample.count()); |
232 for (size_t k = 0; k < arraysize(profile_sample_frames[i][j]); ++k) { | 232 for (size_t k = 0; k < arraysize(profile_sample_frames[i][j]); ++k) { |
233 SCOPED_TRACE("frame " + base::SizeTToString(k)); | 233 SCOPED_TRACE("frame " + base::SizeTToString(k)); |
234 const CallStackProfile::Entry& entry = proto_sample.entry().Get(k); | 234 const CallStackProfile::Entry& entry = proto_sample.entry().Get(k); |
235 ASSERT_TRUE(entry.has_address()); | 235 ASSERT_TRUE(entry.has_address()); |
236 const char* instruction_pointer = reinterpret_cast<const char*>( | 236 const char* instruction_pointer = reinterpret_cast<const char*>( |
237 profile_sample_frames[i][j][k].instruction_pointer); | 237 profile_sample_frames[i][j][k].instruction_pointer); |
238 const char* module_base_address = reinterpret_cast<const char*>( | 238 const char* module_base_address = reinterpret_cast<const char*>( |
239 profile_modules[i][profile_sample_frames[i][j][k].module_index] | 239 profile_modules[i][profile_sample_frames[i][j][k].module_index] |
240 .base_address); | 240 .base_address); |
241 EXPECT_EQ(static_cast<uint64>(instruction_pointer - | 241 EXPECT_EQ( |
242 module_base_address), entry.address()); | 242 static_cast<uint64_t>(instruction_pointer - module_base_address), |
| 243 entry.address()); |
243 ASSERT_TRUE(entry.has_module_id_index()); | 244 ASSERT_TRUE(entry.has_module_id_index()); |
244 EXPECT_EQ(profile_sample_frames[i][j][k].module_index, | 245 EXPECT_EQ(profile_sample_frames[i][j][k].module_index, |
245 static_cast<size_t>(entry.module_id_index())); | 246 static_cast<size_t>(entry.module_id_index())); |
246 } | 247 } |
247 } | 248 } |
248 | 249 |
249 ASSERT_EQ(static_cast<int>(arraysize(profile_modules[i])), | 250 ASSERT_EQ(static_cast<int>(arraysize(profile_modules[i])), |
250 call_stack_profile.module_id().size()); | 251 call_stack_profile.module_id().size()); |
251 for (size_t j = 0; j < arraysize(profile_modules[i]); ++j) { | 252 for (size_t j = 0; j < arraysize(profile_modules[i]); ++j) { |
252 SCOPED_TRACE("module " + base::SizeTToString(j)); | 253 SCOPED_TRACE("module " + base::SizeTToString(j)); |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
333 ASSERT_TRUE(proto_sample.has_count()); | 334 ASSERT_TRUE(proto_sample.has_count()); |
334 EXPECT_EQ(i == 0 ? 3u : 1u, proto_sample.count()); | 335 EXPECT_EQ(i == 0 ? 3u : 1u, proto_sample.count()); |
335 for (size_t j = 0; j < arraysize(sample_frames[i]); ++j) { | 336 for (size_t j = 0; j < arraysize(sample_frames[i]); ++j) { |
336 SCOPED_TRACE("frame " + base::SizeTToString(j)); | 337 SCOPED_TRACE("frame " + base::SizeTToString(j)); |
337 const CallStackProfile::Entry& entry = proto_sample.entry().Get(j); | 338 const CallStackProfile::Entry& entry = proto_sample.entry().Get(j); |
338 ASSERT_TRUE(entry.has_address()); | 339 ASSERT_TRUE(entry.has_address()); |
339 const char* instruction_pointer = reinterpret_cast<const char*>( | 340 const char* instruction_pointer = reinterpret_cast<const char*>( |
340 sample_frames[i][j].instruction_pointer); | 341 sample_frames[i][j].instruction_pointer); |
341 const char* module_base_address = reinterpret_cast<const char*>( | 342 const char* module_base_address = reinterpret_cast<const char*>( |
342 modules[sample_frames[i][j].module_index].base_address); | 343 modules[sample_frames[i][j].module_index].base_address); |
343 EXPECT_EQ(static_cast<uint64>(instruction_pointer - module_base_address), | 344 EXPECT_EQ( |
344 entry.address()); | 345 static_cast<uint64_t>(instruction_pointer - module_base_address), |
| 346 entry.address()); |
345 ASSERT_TRUE(entry.has_module_id_index()); | 347 ASSERT_TRUE(entry.has_module_id_index()); |
346 EXPECT_EQ(sample_frames[i][j].module_index, | 348 EXPECT_EQ(sample_frames[i][j].module_index, |
347 static_cast<size_t>(entry.module_id_index())); | 349 static_cast<size_t>(entry.module_id_index())); |
348 } | 350 } |
349 } | 351 } |
350 } | 352 } |
351 | 353 |
352 // Checks that only contiguous duplicate samples are collapsed with | 354 // Checks that only contiguous duplicate samples are collapsed with |
353 // preserve_sample_ordering = true. | 355 // preserve_sample_ordering = true. |
354 TEST_F(CallStackProfileMetricsProviderTest, RepeatedStacksOrdered) { | 356 TEST_F(CallStackProfileMetricsProviderTest, RepeatedStacksOrdered) { |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
411 ASSERT_TRUE(proto_sample.has_count()); | 413 ASSERT_TRUE(proto_sample.has_count()); |
412 EXPECT_EQ(i == 2 ? 2u : 1u, proto_sample.count()); | 414 EXPECT_EQ(i == 2 ? 2u : 1u, proto_sample.count()); |
413 for (size_t j = 0; j < arraysize(sample_frames[i]); ++j) { | 415 for (size_t j = 0; j < arraysize(sample_frames[i]); ++j) { |
414 SCOPED_TRACE("frame " + base::SizeTToString(j)); | 416 SCOPED_TRACE("frame " + base::SizeTToString(j)); |
415 const CallStackProfile::Entry& entry = proto_sample.entry().Get(j); | 417 const CallStackProfile::Entry& entry = proto_sample.entry().Get(j); |
416 ASSERT_TRUE(entry.has_address()); | 418 ASSERT_TRUE(entry.has_address()); |
417 const char* instruction_pointer = reinterpret_cast<const char*>( | 419 const char* instruction_pointer = reinterpret_cast<const char*>( |
418 sample_frames[i][j].instruction_pointer); | 420 sample_frames[i][j].instruction_pointer); |
419 const char* module_base_address = reinterpret_cast<const char*>( | 421 const char* module_base_address = reinterpret_cast<const char*>( |
420 modules[sample_frames[i][j].module_index].base_address); | 422 modules[sample_frames[i][j].module_index].base_address); |
421 EXPECT_EQ(static_cast<uint64>(instruction_pointer - module_base_address), | 423 EXPECT_EQ( |
422 entry.address()); | 424 static_cast<uint64_t>(instruction_pointer - module_base_address), |
| 425 entry.address()); |
423 ASSERT_TRUE(entry.has_module_id_index()); | 426 ASSERT_TRUE(entry.has_module_id_index()); |
424 EXPECT_EQ(sample_frames[i][j].module_index, | 427 EXPECT_EQ(sample_frames[i][j].module_index, |
425 static_cast<size_t>(entry.module_id_index())); | 428 static_cast<size_t>(entry.module_id_index())); |
426 } | 429 } |
427 } | 430 } |
428 } | 431 } |
429 | 432 |
430 // Checks that unknown modules produce an empty Entry. | 433 // Checks that unknown modules produce an empty Entry. |
431 TEST_F(CallStackProfileMetricsProviderTest, UnknownModule) { | 434 TEST_F(CallStackProfileMetricsProviderTest, UnknownModule) { |
432 const Frame frame(0x1000, Frame::kUnknownModuleIndex); | 435 const Frame frame(0x1000, Frame::kUnknownModuleIndex); |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
607 | 610 |
608 provider.OnRecordingEnabled(); | 611 provider.OnRecordingEnabled(); |
609 callback.Run(std::vector<Profile>(1, profile)); | 612 callback.Run(std::vector<Profile>(1, profile)); |
610 ChromeUserMetricsExtension uma_proto; | 613 ChromeUserMetricsExtension uma_proto; |
611 provider.ProvideGeneralMetrics(&uma_proto); | 614 provider.ProvideGeneralMetrics(&uma_proto); |
612 | 615 |
613 EXPECT_EQ(0, uma_proto.sampled_profile_size()); | 616 EXPECT_EQ(0, uma_proto.sampled_profile_size()); |
614 } | 617 } |
615 | 618 |
616 } // namespace metrics | 619 } // namespace metrics |
OLD | NEW |