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 <sstream> | 5 #include <sstream> |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/compiler_specific.h" | 8 #include "base/compiler_specific.h" |
9 #include "base/path_service.h" | 9 #include "base/path_service.h" |
10 #include "base/profiler/stack_sampling_profiler.h" | 10 #include "base/profiler/stack_sampling_profiler.h" |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
84 #pragma optimize("", on) | 84 #pragma optimize("", on) |
85 #endif | 85 #endif |
86 | 86 |
87 // Called on the profiler thread when complete. Collects profiles produced by | 87 // Called on the profiler thread when complete. Collects profiles produced by |
88 // the profiler, and signals an event to allow the main thread to know that that | 88 // the profiler, and signals an event to allow the main thread to know that that |
89 // the profiler is done. | 89 // the profiler is done. |
90 void SaveProfilesAndSignalEvent(std::vector<Profile>* profiles, | 90 void SaveProfilesAndSignalEvent(std::vector<Profile>* profiles, |
91 WaitableEvent* event, | 91 WaitableEvent* event, |
92 const std::vector<Profile>& pending_profiles) { | 92 const std::vector<Profile>& pending_profiles) { |
93 *profiles = pending_profiles; | 93 *profiles = pending_profiles; |
94 event->Signal(); | 94 if (event) |
| 95 event->Signal(); |
95 } | 96 } |
96 | 97 |
97 // Captures profiles as specified by |params| on the TargetThread, and returns | 98 // Captures profiles as specified by |params| on the TargetThread, and returns |
98 // them in |profiles|. Waits up to |profiler_wait_time| for the profiler to | 99 // them in |profiles|. Waits up to |profiler_wait_time| for the profiler to |
99 // complete. | 100 // complete. Uses a per-object callback unless |use_default_callback| is true. |
100 void CaptureProfiles(const StackSamplingProfiler::SamplingParams& params, | 101 void CaptureProfiles(const StackSamplingProfiler::SamplingParams& params, |
101 std::vector<Profile>* profiles, | 102 std::vector<Profile>* profiles, |
102 TimeDelta profiler_wait_time) { | 103 TimeDelta profiler_wait_time, bool use_default_callback) { |
103 TargetThread target_thread; | 104 TargetThread target_thread; |
104 PlatformThreadHandle target_thread_handle; | 105 PlatformThreadHandle target_thread_handle; |
105 EXPECT_TRUE(PlatformThread::Create(0, &target_thread, &target_thread_handle)); | 106 EXPECT_TRUE(PlatformThread::Create(0, &target_thread, &target_thread_handle)); |
106 | 107 |
107 target_thread.WaitForThreadStart(); | 108 target_thread.WaitForThreadStart(); |
108 | 109 |
109 WaitableEvent sampling_thread_completed(true, false); | 110 WaitableEvent sampling_thread_completed(true, false); |
110 profiles->clear(); | 111 profiles->clear(); |
| 112 const StackSamplingProfiler::CompletedCallback callback = |
| 113 Bind(&SaveProfilesAndSignalEvent, Unretained(profiles), |
| 114 Unretained(&sampling_thread_completed)); |
| 115 scoped_ptr<StackSamplingProfiler> profiler; |
| 116 if (use_default_callback) { |
| 117 StackSamplingProfiler::SetDefaultCompletedCallback(callback); |
| 118 profiler.reset(new StackSamplingProfiler(target_thread.id(), params)); |
| 119 } else { |
| 120 profiler.reset(new StackSamplingProfiler(target_thread.id(), params, |
| 121 callback)); |
| 122 } |
| 123 profiler->Start(); |
| 124 sampling_thread_completed.TimedWait(profiler_wait_time); |
| 125 profiler->Stop(); |
| 126 sampling_thread_completed.Wait(); |
| 127 |
| 128 target_thread.SignalThreadToFinish(); |
| 129 |
| 130 PlatformThread::Join(target_thread_handle); |
| 131 |
| 132 if (use_default_callback) { |
| 133 StackSamplingProfiler::SetDefaultCompletedCallback( |
| 134 StackSamplingProfiler::CompletedCallback()); |
| 135 } |
| 136 } |
| 137 |
| 138 // Captures profiles as specified by |params| on the TargetThread, and returns |
| 139 // them in |profiles|. Waits up to |profiler_wait_time| for the profiler to |
| 140 // complete. |
| 141 void CaptureProfilesWithObjectCallback( |
| 142 const StackSamplingProfiler::SamplingParams& params, |
| 143 std::vector<Profile>* profiles, |
| 144 TimeDelta profiler_wait_time) { |
| 145 CaptureProfiles(params, profiles, profiler_wait_time, false); |
| 146 } |
| 147 |
| 148 // Captures profiles as specified by |params| on the TargetThread, and returns |
| 149 // them in |profiles|. Uses the default callback rather than a per-object |
| 150 // callback. Waits up to |profiler_wait_time| for the profiler to complete. |
| 151 void CaptureProfilesWithDefaultCallback( |
| 152 const StackSamplingProfiler::SamplingParams& params, |
| 153 std::vector<Profile>* profiles, |
| 154 TimeDelta profiler_wait_time) { |
| 155 CaptureProfiles(params, profiles, profiler_wait_time, true); |
| 156 } |
| 157 |
| 158 // Runs the profiler with |params| on the TargetThread, with no default or |
| 159 // per-object callback. |
| 160 void RunProfilerWithNoCallback( |
| 161 const StackSamplingProfiler::SamplingParams& params, |
| 162 TimeDelta profiler_wait_time) { |
| 163 TargetThread target_thread; |
| 164 PlatformThreadHandle target_thread_handle; |
| 165 EXPECT_TRUE(PlatformThread::Create(0, &target_thread, &target_thread_handle)); |
| 166 |
| 167 target_thread.WaitForThreadStart(); |
| 168 |
111 StackSamplingProfiler profiler(target_thread.id(), params); | 169 StackSamplingProfiler profiler(target_thread.id(), params); |
112 profiler.SetCustomCompletedCallback( | |
113 Bind(&SaveProfilesAndSignalEvent, Unretained(profiles), | |
114 Unretained(&sampling_thread_completed))); | |
115 profiler.Start(); | 170 profiler.Start(); |
116 sampling_thread_completed.TimedWait(profiler_wait_time); | 171 // Since we don't specify a callback, we don't have a synchronization |
| 172 // mechanism with the sampling thread. Just sleep instead. |
| 173 PlatformThread::Sleep(profiler_wait_time); |
117 profiler.Stop(); | 174 profiler.Stop(); |
118 sampling_thread_completed.Wait(); | |
119 | 175 |
120 target_thread.SignalThreadToFinish(); | 176 target_thread.SignalThreadToFinish(); |
121 | 177 |
122 PlatformThread::Join(target_thread_handle); | 178 PlatformThread::Join(target_thread_handle); |
123 } | 179 } |
124 | 180 |
125 // If this executable was linked with /INCREMENTAL (the default for non-official | 181 // If this executable was linked with /INCREMENTAL (the default for non-official |
126 // debug and release builds on Windows), function addresses do not correspond to | 182 // debug and release builds on Windows), function addresses do not correspond to |
127 // function code itself, but instead to instructions in the Incremental Link | 183 // function code itself, but instead to instructions in the Incremental Link |
128 // Table that jump to the functions. Check for a jump instruction and if present | 184 // Table that jump to the functions. Check for a jump instruction and if present |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
191 #define MAYBE_Basic DISABLED_Basic | 247 #define MAYBE_Basic DISABLED_Basic |
192 #endif | 248 #endif |
193 TEST(StackSamplingProfilerTest, MAYBE_Basic) { | 249 TEST(StackSamplingProfilerTest, MAYBE_Basic) { |
194 StackSamplingProfiler::SamplingParams params; | 250 StackSamplingProfiler::SamplingParams params; |
195 params.initial_delay = params.burst_interval = params.sampling_interval = | 251 params.initial_delay = params.burst_interval = params.sampling_interval = |
196 TimeDelta::FromMilliseconds(0); | 252 TimeDelta::FromMilliseconds(0); |
197 params.bursts = 1; | 253 params.bursts = 1; |
198 params.samples_per_burst = 1; | 254 params.samples_per_burst = 1; |
199 | 255 |
200 std::vector<Profile> profiles; | 256 std::vector<Profile> profiles; |
201 CaptureProfiles(params, &profiles, AVeryLongTimeDelta()); | 257 CaptureProfilesWithObjectCallback(params, &profiles, AVeryLongTimeDelta()); |
202 | 258 |
203 // Check that the profile and samples sizes are correct, and the module | 259 // Check that the profile and samples sizes are correct, and the module |
204 // indices are in range. | 260 // indices are in range. |
205 | 261 |
206 ASSERT_EQ(1u, profiles.size()); | 262 ASSERT_EQ(1u, profiles.size()); |
207 const Profile& profile = profiles[0]; | 263 const Profile& profile = profiles[0]; |
208 ASSERT_EQ(1u, profile.samples.size()); | 264 ASSERT_EQ(1u, profile.samples.size()); |
209 EXPECT_EQ(params.sampling_interval, profile.sampling_period); | 265 EXPECT_EQ(params.sampling_interval, profile.sampling_period); |
210 const Sample& sample = profile.samples[0]; | 266 const Sample& sample = profile.samples[0]; |
211 for (const auto& frame : sample) { | 267 for (const auto& frame : sample) { |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
245 #define MAYBE_MultipleProfilesAndSamples DISABLED_MultipleProfilesAndSamples | 301 #define MAYBE_MultipleProfilesAndSamples DISABLED_MultipleProfilesAndSamples |
246 #endif | 302 #endif |
247 TEST(StackSamplingProfilerTest, MAYBE_MultipleProfilesAndSamples) { | 303 TEST(StackSamplingProfilerTest, MAYBE_MultipleProfilesAndSamples) { |
248 StackSamplingProfiler::SamplingParams params; | 304 StackSamplingProfiler::SamplingParams params; |
249 params.initial_delay = params.burst_interval = params.sampling_interval = | 305 params.initial_delay = params.burst_interval = params.sampling_interval = |
250 TimeDelta::FromMilliseconds(0); | 306 TimeDelta::FromMilliseconds(0); |
251 params.bursts = 2; | 307 params.bursts = 2; |
252 params.samples_per_burst = 3; | 308 params.samples_per_burst = 3; |
253 | 309 |
254 std::vector<Profile> profiles; | 310 std::vector<Profile> profiles; |
255 CaptureProfiles(params, &profiles, AVeryLongTimeDelta()); | 311 CaptureProfilesWithObjectCallback(params, &profiles, AVeryLongTimeDelta()); |
256 | 312 |
257 ASSERT_EQ(2u, profiles.size()); | 313 ASSERT_EQ(2u, profiles.size()); |
258 EXPECT_EQ(3u, profiles[0].samples.size()); | 314 EXPECT_EQ(3u, profiles[0].samples.size()); |
259 EXPECT_EQ(3u, profiles[1].samples.size()); | 315 EXPECT_EQ(3u, profiles[1].samples.size()); |
260 } | 316 } |
261 | 317 |
262 // Checks that no profiles are captured if the profiling is stopped during the | 318 // Checks that no profiles are captured if the profiling is stopped during the |
263 // initial delay. | 319 // initial delay. |
264 #if defined(_WIN64) | 320 #if defined(_WIN64) |
265 #define MAYBE_StopDuringInitialDelay StopDuringInitialDelay | 321 #define MAYBE_StopDuringInitialDelay StopDuringInitialDelay |
266 #else | 322 #else |
267 #define MAYBE_StopDuringInitialDelay DISABLED_StopDuringInitialDelay | 323 #define MAYBE_StopDuringInitialDelay DISABLED_StopDuringInitialDelay |
268 #endif | 324 #endif |
269 TEST(StackSamplingProfilerTest, MAYBE_StopDuringInitialDelay) { | 325 TEST(StackSamplingProfilerTest, MAYBE_StopDuringInitialDelay) { |
270 StackSamplingProfiler::SamplingParams params; | 326 StackSamplingProfiler::SamplingParams params; |
271 params.burst_interval = params.sampling_interval = | 327 params.burst_interval = params.sampling_interval = |
272 TimeDelta::FromMilliseconds(0); | 328 TimeDelta::FromMilliseconds(0); |
273 params.initial_delay = TimeDelta::FromSeconds(60); | 329 params.initial_delay = TimeDelta::FromSeconds(60); |
274 params.bursts = params.samples_per_burst = 1; | 330 params.bursts = params.samples_per_burst = 1; |
275 | 331 |
276 std::vector<Profile> profiles; | 332 std::vector<Profile> profiles; |
277 CaptureProfiles(params, &profiles, TimeDelta::FromMilliseconds(0)); | 333 CaptureProfilesWithObjectCallback(params, &profiles, |
| 334 TimeDelta::FromMilliseconds(0)); |
278 | 335 |
279 EXPECT_TRUE(profiles.empty()); | 336 EXPECT_TRUE(profiles.empty()); |
280 } | 337 } |
281 | 338 |
282 // Checks that the single completed profile is captured if the profiling is | 339 // Checks that the single completed profile is captured if the profiling is |
283 // stopped between bursts. | 340 // stopped between bursts. |
284 #if defined(_WIN64) | 341 #if defined(_WIN64) |
285 #define MAYBE_StopDuringInterBurstInterval StopDuringInterBurstInterval | 342 #define MAYBE_StopDuringInterBurstInterval StopDuringInterBurstInterval |
286 #else | 343 #else |
287 #define MAYBE_StopDuringInterBurstInterval DISABLED_StopDuringInterBurstInterval | 344 #define MAYBE_StopDuringInterBurstInterval DISABLED_StopDuringInterBurstInterval |
288 #endif | 345 #endif |
289 TEST(StackSamplingProfilerTest, MAYBE_StopDuringInterBurstInterval) { | 346 TEST(StackSamplingProfilerTest, MAYBE_StopDuringInterBurstInterval) { |
290 StackSamplingProfiler::SamplingParams params; | 347 StackSamplingProfiler::SamplingParams params; |
291 params.initial_delay = params.sampling_interval = | 348 params.initial_delay = params.sampling_interval = |
292 TimeDelta::FromMilliseconds(0); | 349 TimeDelta::FromMilliseconds(0); |
293 params.burst_interval = TimeDelta::FromSeconds(60); | 350 params.burst_interval = TimeDelta::FromSeconds(60); |
294 params.bursts = 2; | 351 params.bursts = 2; |
295 params.samples_per_burst = 1; | 352 params.samples_per_burst = 1; |
296 | 353 |
297 std::vector<Profile> profiles; | 354 std::vector<Profile> profiles; |
298 CaptureProfiles(params, &profiles, TimeDelta::FromMilliseconds(50)); | 355 CaptureProfilesWithObjectCallback(params, &profiles, |
| 356 TimeDelta::FromMilliseconds(50)); |
299 | 357 |
300 ASSERT_EQ(1u, profiles.size()); | 358 ASSERT_EQ(1u, profiles.size()); |
301 EXPECT_EQ(1u, profiles[0].samples.size()); | 359 EXPECT_EQ(1u, profiles[0].samples.size()); |
302 } | 360 } |
303 | 361 |
304 // Checks that only completed profiles are captured. | 362 // Checks that only completed profiles are captured. |
305 #if defined(_WIN64) | 363 #if defined(_WIN64) |
306 #define MAYBE_StopDuringInterSampleInterval StopDuringInterSampleInterval | 364 #define MAYBE_StopDuringInterSampleInterval StopDuringInterSampleInterval |
307 #else | 365 #else |
308 #define MAYBE_StopDuringInterSampleInterval \ | 366 #define MAYBE_StopDuringInterSampleInterval \ |
309 DISABLED_StopDuringInterSampleInterval | 367 DISABLED_StopDuringInterSampleInterval |
310 #endif | 368 #endif |
311 TEST(StackSamplingProfilerTest, MAYBE_StopDuringInterSampleInterval) { | 369 TEST(StackSamplingProfilerTest, MAYBE_StopDuringInterSampleInterval) { |
312 StackSamplingProfiler::SamplingParams params; | 370 StackSamplingProfiler::SamplingParams params; |
313 params.initial_delay = params.burst_interval = TimeDelta::FromMilliseconds(0); | 371 params.initial_delay = params.burst_interval = TimeDelta::FromMilliseconds(0); |
314 params.sampling_interval = TimeDelta::FromSeconds(60); | 372 params.sampling_interval = TimeDelta::FromSeconds(60); |
315 params.bursts = 1; | 373 params.bursts = 1; |
316 params.samples_per_burst = 2; | 374 params.samples_per_burst = 2; |
317 | 375 |
318 std::vector<Profile> profiles; | 376 std::vector<Profile> profiles; |
319 CaptureProfiles(params, &profiles, TimeDelta::FromMilliseconds(50)); | 377 CaptureProfilesWithObjectCallback(params, &profiles, |
| 378 TimeDelta::FromMilliseconds(50)); |
320 | 379 |
321 EXPECT_TRUE(profiles.empty()); | 380 EXPECT_TRUE(profiles.empty()); |
322 } | 381 } |
323 | 382 |
324 } // namespace tracked_objects | 383 // Checks that profiles are captured via the default completed callback. |
| 384 #if defined(_WIN64) |
| 385 #define MAYBE_DefaultCallback DefaultCallback |
| 386 #else |
| 387 #define MAYBE_DefaultCallback DISABLED_DefaultCallback |
| 388 #endif |
| 389 TEST(StackSamplingProfilerTest, MAYBE_DefaultCallback) { |
| 390 StackSamplingProfiler::SamplingParams params; |
| 391 params.initial_delay = params.burst_interval = params.sampling_interval = |
| 392 TimeDelta::FromMilliseconds(0); |
| 393 params.bursts = 1; |
| 394 params.samples_per_burst = 1; |
| 395 |
| 396 std::vector<Profile> profiles; |
| 397 CaptureProfilesWithDefaultCallback(params, &profiles, AVeryLongTimeDelta()); |
| 398 |
| 399 EXPECT_EQ(1u, profiles.size()); |
| 400 EXPECT_EQ(1u, profiles[0].samples.size()); |
| 401 } |
| 402 |
| 403 // Checks that profiles are queued until a default callback is set, then |
| 404 // delivered. |
| 405 #if defined(_WIN64) |
| 406 #define MAYBE_ProfilesQueuedWithNoCallback ProfilesQueuedWithNoCallback |
| 407 #else |
| 408 #define MAYBE_ProfilesQueuedWithNoCallback DISABLED_ProfilesQueuedWithNoCallback |
| 409 #endif |
| 410 TEST(StackSamplingProfilerTest, MAYBE_ProfilesQueuedWithNoCallback) { |
| 411 StackSamplingProfiler::SamplingParams params; |
| 412 params.initial_delay = params.burst_interval = params.sampling_interval = |
| 413 TimeDelta::FromMilliseconds(0); |
| 414 params.bursts = 1; |
| 415 params.samples_per_burst = 1; |
| 416 |
| 417 RunProfilerWithNoCallback(params, TimeDelta::FromMilliseconds(50)); |
| 418 |
| 419 std::vector<Profile> profiles; |
| 420 // This should immediately call SaveProfilesAndSignalEvent on this thread. |
| 421 StackSamplingProfiler::SetDefaultCompletedCallback( |
| 422 Bind(&SaveProfilesAndSignalEvent, Unretained(&profiles), nullptr)); |
| 423 EXPECT_EQ(1u, profiles.size()); |
| 424 EXPECT_EQ(1u, profiles[0].samples.size()); |
| 425 StackSamplingProfiler::SetDefaultCompletedCallback( |
| 426 StackSamplingProfiler::CompletedCallback()); |
| 427 } |
| 428 |
| 429 } // namespace base |
OLD | NEW |