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) { | |
Mike Wittman
2015/03/24 18:37:39
This test and the following one need to be run ind
| |
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 |