Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(79)

Side by Side Diff: base/profiler/stack_sampling_profiler_unittest.cc

Issue 2554123002: Support parallel captures from the StackSamplingProfiler. (Closed)
Patch Set: fixed signed/unsigned comparison in test Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « base/profiler/stack_sampling_profiler.cc ('k') | base/threading/thread_restrictions.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 <stddef.h> 5 #include <stddef.h>
6 #include <stdint.h> 6 #include <stdint.h>
7 7
8 #include <cstdlib> 8 #include <cstdlib>
9 #include <memory> 9 #include <memory>
10 #include <utility> 10 #include <utility>
11 #include <vector> 11 #include <vector>
12 12
13 #include "base/bind.h" 13 #include "base/bind.h"
14 #include "base/compiler_specific.h" 14 #include "base/compiler_specific.h"
15 #include "base/macros.h" 15 #include "base/macros.h"
16 #include "base/memory/ptr_util.h" 16 #include "base/memory/ptr_util.h"
17 #include "base/message_loop/message_loop.h"
18 #include "base/native_library.h" 17 #include "base/native_library.h"
19 #include "base/path_service.h" 18 #include "base/path_service.h"
20 #include "base/profiler/native_stack_sampler.h" 19 #include "base/profiler/native_stack_sampler.h"
21 #include "base/profiler/stack_sampling_profiler.h" 20 #include "base/profiler/stack_sampling_profiler.h"
22 #include "base/run_loop.h" 21 #include "base/run_loop.h"
23 #include "base/scoped_native_library.h" 22 #include "base/scoped_native_library.h"
24 #include "base/strings/stringprintf.h" 23 #include "base/strings/stringprintf.h"
25 #include "base/strings/utf_string_conversions.h" 24 #include "base/strings/utf_string_conversions.h"
25 #include "base/synchronization/lock.h"
26 #include "base/synchronization/waitable_event.h" 26 #include "base/synchronization/waitable_event.h"
27 #include "base/threading/platform_thread.h" 27 #include "base/threading/platform_thread.h"
28 #include "base/threading/simple_thread.h"
28 #include "base/time/time.h" 29 #include "base/time/time.h"
29 #include "build/build_config.h" 30 #include "build/build_config.h"
30 #include "testing/gtest/include/gtest/gtest.h" 31 #include "testing/gtest/include/gtest/gtest.h"
31 32
32 #if defined(OS_WIN) 33 #if defined(OS_WIN)
33 #include <intrin.h> 34 #include <intrin.h>
34 #include <malloc.h> 35 #include <malloc.h>
35 #include <windows.h> 36 #include <windows.h>
36 #else 37 #else
37 #include <alloca.h> 38 #include <alloca.h>
(...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after
344 target_thread.SignalThreadToFinish(); 345 target_thread.SignalThreadToFinish();
345 346
346 PlatformThread::Join(target_thread_handle); 347 PlatformThread::Join(target_thread_handle);
347 } 348 }
348 349
349 template <class Function> 350 template <class Function>
350 void WithTargetThread(Function function) { 351 void WithTargetThread(Function function) {
351 WithTargetThread(function, StackConfiguration(StackConfiguration::NORMAL)); 352 WithTargetThread(function, StackConfiguration(StackConfiguration::NORMAL));
352 } 353 }
353 354
355 // Waits for one of multiple samplings to complete. If |delegates| is provided,
356 // the vector must be pre-populated and of the same size as |params|.
357 void CreateProfilers(
358 PlatformThreadId target_thread_id,
359 const std::vector<SamplingParams>& params,
360 const std::vector<std::unique_ptr<NativeStackSamplerTestDelegate>>*
361 delegates,
362 std::vector<CallStackProfiles>* profiles,
363 std::vector<std::unique_ptr<StackSamplingProfiler>>* profilers,
364 std::vector<std::unique_ptr<WaitableEvent>>* completed) {
365 ASSERT_TRUE(!params.empty());
366 ASSERT_TRUE(profiles->empty());
367 ASSERT_TRUE(profilers->empty());
368 ASSERT_TRUE(completed->empty());
369 if (delegates)
370 ASSERT_EQ(params.size(), delegates->size());
371
372 // Vectors have to be appropriately sized in advance so that the addresses of
373 // values don't change.
374 const size_t count = params.size();
375 profiles->reserve(count);
376 profilers->reserve(count);
377 completed->reserve(count);
378
379 for (size_t i = 0; i < count; ++i) {
380 profiles->push_back(CallStackProfiles());
381 completed->push_back(
382 MakeUnique<WaitableEvent>(WaitableEvent::ResetPolicy::AUTOMATIC,
383 WaitableEvent::InitialState::NOT_SIGNALED));
384 const StackSamplingProfiler::CompletedCallback callback =
385 Bind(&SaveProfilesAndSignalEvent, Unretained(&profiles->back()),
386 Unretained(completed->back().get()));
387 profilers->push_back(MakeUnique<StackSamplingProfiler>(
388 target_thread_id, params[i], callback,
389 (delegates ? (*delegates)[i].get() : nullptr)));
390 }
391 }
392
354 // Captures profiles as specified by |params| on the TargetThread, and returns 393 // Captures profiles as specified by |params| on the TargetThread, and returns
355 // them in |profiles|. Waits up to |profiler_wait_time| for the profiler to 394 // them in |profiles|. Waits up to |profiler_wait_time| for the profiler to
356 // complete. 395 // complete.
357 void CaptureProfiles(const SamplingParams& params, TimeDelta profiler_wait_time, 396 void CaptureProfiles(const SamplingParams& params, TimeDelta profiler_wait_time,
358 CallStackProfiles* profiles) { 397 CallStackProfiles* profiles) {
359 profiles->clear(); 398 profiles->clear();
360 399
361 WithTargetThread([&params, profiles, 400 WithTargetThread([&params, profiles,
362 profiler_wait_time](PlatformThreadId target_thread_id) { 401 profiler_wait_time](PlatformThreadId target_thread_id) {
363 WaitableEvent sampling_thread_completed( 402 WaitableEvent sampling_thread_completed(
364 WaitableEvent::ResetPolicy::MANUAL, 403 WaitableEvent::ResetPolicy::MANUAL,
365 WaitableEvent::InitialState::NOT_SIGNALED); 404 WaitableEvent::InitialState::NOT_SIGNALED);
366 const StackSamplingProfiler::CompletedCallback callback = 405 const StackSamplingProfiler::CompletedCallback callback =
367 Bind(&SaveProfilesAndSignalEvent, Unretained(profiles), 406 Bind(&SaveProfilesAndSignalEvent, Unretained(profiles),
368 Unretained(&sampling_thread_completed)); 407 Unretained(&sampling_thread_completed));
369 StackSamplingProfiler profiler(target_thread_id, params, callback); 408 StackSamplingProfiler profiler(target_thread_id, params, callback);
370 profiler.Start(); 409 profiler.Start();
371 sampling_thread_completed.TimedWait(profiler_wait_time); 410 sampling_thread_completed.TimedWait(profiler_wait_time);
372 profiler.Stop(); 411 profiler.Stop();
373 sampling_thread_completed.Wait(); 412 sampling_thread_completed.Wait();
374 }); 413 });
375 } 414 }
376 415
416 // Waits for one of multiple samplings to complete.
417 size_t WaitForSamplingComplete(
418 std::vector<std::unique_ptr<WaitableEvent>>* sampling_completed) {
419 // Map unique_ptrs to something that WaitMany can accept.
420 std::vector<WaitableEvent*> sampling_completed_rawptrs(
421 sampling_completed->size());
422 std::transform(
423 sampling_completed->begin(), sampling_completed->end(),
424 sampling_completed_rawptrs.begin(),
425 [](const std::unique_ptr<WaitableEvent>& elem) { return elem.get(); });
426 // Wait for one profiler to finish.
427 return WaitableEvent::WaitMany(sampling_completed_rawptrs.data(),
428 sampling_completed_rawptrs.size());
429 }
430
377 // If this executable was linked with /INCREMENTAL (the default for non-official 431 // If this executable was linked with /INCREMENTAL (the default for non-official
378 // debug and release builds on Windows), function addresses do not correspond to 432 // debug and release builds on Windows), function addresses do not correspond to
379 // function code itself, but instead to instructions in the Incremental Link 433 // function code itself, but instead to instructions in the Incremental Link
380 // Table that jump to the functions. Checks for a jump instruction and if 434 // Table that jump to the functions. Checks for a jump instruction and if
381 // present does a little decompilation to find the function's actual starting 435 // present does a little decompilation to find the function's actual starting
382 // address. 436 // address.
383 const void* MaybeFixupFunctionAddressForILT(const void* function_address) { 437 const void* MaybeFixupFunctionAddressForILT(const void* function_address) {
384 #if defined(_WIN64) 438 #if defined(_WIN64)
385 const unsigned char* opcode = 439 const unsigned char* opcode =
386 reinterpret_cast<const unsigned char*>(function_address); 440 reinterpret_cast<const unsigned char*>(function_address);
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
437 // asynchronous library loading has completed before walking the stack. If 491 // asynchronous library loading has completed before walking the stack. If
438 // false, the unloading may still be occurring during the stack walk. 492 // false, the unloading may still be occurring during the stack walk.
439 void TestLibraryUnload(bool wait_until_unloaded) { 493 void TestLibraryUnload(bool wait_until_unloaded) {
440 // Test delegate that supports intervening between the copying of the stack 494 // Test delegate that supports intervening between the copying of the stack
441 // and the walking of the stack. 495 // and the walking of the stack.
442 class StackCopiedSignaler : public NativeStackSamplerTestDelegate { 496 class StackCopiedSignaler : public NativeStackSamplerTestDelegate {
443 public: 497 public:
444 StackCopiedSignaler(WaitableEvent* stack_copied, 498 StackCopiedSignaler(WaitableEvent* stack_copied,
445 WaitableEvent* start_stack_walk, 499 WaitableEvent* start_stack_walk,
446 bool wait_to_walk_stack) 500 bool wait_to_walk_stack)
447 : stack_copied_(stack_copied), start_stack_walk_(start_stack_walk), 501 : stack_copied_(stack_copied),
448 wait_to_walk_stack_(wait_to_walk_stack) { 502 start_stack_walk_(start_stack_walk),
449 } 503 wait_to_walk_stack_(wait_to_walk_stack) {}
450 504
451 void OnPreStackWalk() override { 505 void OnPreStackWalk() override {
452 stack_copied_->Signal(); 506 stack_copied_->Signal();
453 if (wait_to_walk_stack_) 507 if (wait_to_walk_stack_)
454 start_stack_walk_->Wait(); 508 start_stack_walk_->Wait();
455 } 509 }
456 510
457 private: 511 private:
458 WaitableEvent* const stack_copied_; 512 WaitableEvent* const stack_copied_;
459 WaitableEvent* const start_stack_walk_; 513 WaitableEvent* const start_stack_walk_;
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
570 // TargetThread::SignalAndWaitUntilSignaled 624 // TargetThread::SignalAndWaitUntilSignaled
571 // TargetThread::OtherLibraryCallback 625 // TargetThread::OtherLibraryCallback
572 // InvokeCallbackFunction (in other library) 626 // InvokeCallbackFunction (in other library)
573 // TargetThread::CallThroughOtherLibrary 627 // TargetThread::CallThroughOtherLibrary
574 EXPECT_EQ(3, other_library_frame - end_frame) 628 EXPECT_EQ(3, other_library_frame - end_frame)
575 << "Stack:\n" 629 << "Stack:\n"
576 << FormatSampleForDiagnosticOutput(sample, profile.modules); 630 << FormatSampleForDiagnosticOutput(sample, profile.modules);
577 } 631 }
578 } 632 }
579 633
634 class StackSamplingProfilerTest : public testing::Test {
635 public:
636 void SetUp() override {
637 StackSamplingProfiler::ResetAnnotationsForTesting();
Mike Wittman 2017/03/31 01:38:22 Can you move this function into the TestAPI for co
Mike Wittman 2017/03/31 01:38:22 Also, this call should go in TearDown.
bcwhite 2017/03/31 13:57:56 Done. And it makes sense to call that as part of
bcwhite 2017/03/31 13:57:56 Reset needs to happen in SetUp because it's possib
Mike Wittman 2017/03/31 18:12:33 That's a very good point that we need to be concer
bcwhite 2017/04/03 20:18:12 Done.
638 StackSamplingProfiler::TestAPI::DisableIdleShutdown();
Mike Wittman 2017/03/31 01:38:22 It's worth commenting that we disable idle shutdow
bcwhite 2017/03/31 13:57:56 Done.
639 }
640
641 void TearDown() override { StackSamplingProfiler::TestAPI::Reset(); }
642 };
643
580 } // namespace 644 } // namespace
581 645
582 // Checks that the basic expected information is present in a sampled call stack 646 // Checks that the basic expected information is present in a sampled call stack
583 // profile. 647 // profile.
584 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED) 648 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED)
585 #define MAYBE_Basic Basic 649 #define MAYBE_Basic Basic
586 #else 650 #else
587 #define MAYBE_Basic DISABLED_Basic 651 #define MAYBE_Basic DISABLED_Basic
588 #endif 652 #endif
589 TEST(StackSamplingProfilerTest, MAYBE_Basic) { 653 TEST_F(StackSamplingProfilerTest, MAYBE_Basic) {
590 StackSamplingProfiler::ResetAnnotationsForTesting();
591
592 SamplingParams params; 654 SamplingParams params;
593 params.sampling_interval = TimeDelta::FromMilliseconds(0); 655 params.sampling_interval = TimeDelta::FromMilliseconds(0);
594 params.samples_per_burst = 1; 656 params.samples_per_burst = 1;
595 657
596 std::vector<CallStackProfile> profiles; 658 std::vector<CallStackProfile> profiles;
597 CaptureProfiles(params, AVeryLongTimeDelta(), &profiles); 659 CaptureProfiles(params, AVeryLongTimeDelta(), &profiles);
598 660
599 // Check that the profile and samples sizes are correct, and the module 661 // Check that the profile and samples sizes are correct, and the module
600 // indices are in range. 662 // indices are in range.
601 ASSERT_EQ(1u, profiles.size()); 663 ASSERT_EQ(1u, profiles.size());
(...skipping 22 matching lines...) Expand all
624 EXPECT_TRUE(PathService::Get(FILE_EXE, &executable_path)); 686 EXPECT_TRUE(PathService::Get(FILE_EXE, &executable_path));
625 EXPECT_EQ(executable_path, profile.modules[loc->module_index].filename); 687 EXPECT_EQ(executable_path, profile.modules[loc->module_index].filename);
626 } 688 }
627 689
628 // Checks that annotations are recorded in samples. 690 // Checks that annotations are recorded in samples.
629 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED) 691 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED)
630 #define MAYBE_Annotations Annotations 692 #define MAYBE_Annotations Annotations
631 #else 693 #else
632 #define MAYBE_Annotations DISABLED_Annotations 694 #define MAYBE_Annotations DISABLED_Annotations
633 #endif 695 #endif
634 TEST(StackSamplingProfilerTest, MAYBE_Annotations) { 696 TEST_F(StackSamplingProfilerTest, MAYBE_Annotations) {
635 StackSamplingProfiler::ResetAnnotationsForTesting();
636
637 SamplingParams params; 697 SamplingParams params;
638 params.sampling_interval = TimeDelta::FromMilliseconds(0); 698 params.sampling_interval = TimeDelta::FromMilliseconds(0);
639 params.samples_per_burst = 1; 699 params.samples_per_burst = 1;
640 700
641 // Check that a run picks up annotations. 701 // Check that a run picks up annotations.
642 StackSamplingProfiler::SetProcessMilestone(1); 702 StackSamplingProfiler::SetProcessMilestone(1);
643 std::vector<CallStackProfile> profiles1; 703 std::vector<CallStackProfile> profiles1;
644 CaptureProfiles(params, AVeryLongTimeDelta(), &profiles1); 704 CaptureProfiles(params, AVeryLongTimeDelta(), &profiles1);
645 ASSERT_EQ(1u, profiles1.size()); 705 ASSERT_EQ(1u, profiles1.size());
646 const CallStackProfile& profile1 = profiles1[0]; 706 const CallStackProfile& profile1 = profiles1[0];
(...skipping 13 matching lines...) Expand all
660 EXPECT_EQ(sample1.process_milestones | (1u << 2), sample2.process_milestones); 720 EXPECT_EQ(sample1.process_milestones | (1u << 2), sample2.process_milestones);
661 } 721 }
662 722
663 // Checks that the profiler handles stacks containing dynamically-allocated 723 // Checks that the profiler handles stacks containing dynamically-allocated
664 // stack memory. 724 // stack memory.
665 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED) 725 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED)
666 #define MAYBE_Alloca Alloca 726 #define MAYBE_Alloca Alloca
667 #else 727 #else
668 #define MAYBE_Alloca DISABLED_Alloca 728 #define MAYBE_Alloca DISABLED_Alloca
669 #endif 729 #endif
670 TEST(StackSamplingProfilerTest, MAYBE_Alloca) { 730 TEST_F(StackSamplingProfilerTest, MAYBE_Alloca) {
671 SamplingParams params; 731 SamplingParams params;
672 params.sampling_interval = TimeDelta::FromMilliseconds(0); 732 params.sampling_interval = TimeDelta::FromMilliseconds(0);
673 params.samples_per_burst = 1; 733 params.samples_per_burst = 1;
674 734
675 std::vector<CallStackProfile> profiles; 735 std::vector<CallStackProfile> profiles;
676 WithTargetThread( 736 WithTargetThread(
677 [&params, &profiles](PlatformThreadId target_thread_id) { 737 [&params, &profiles](PlatformThreadId target_thread_id) {
678 WaitableEvent sampling_thread_completed( 738 WaitableEvent sampling_thread_completed(
679 WaitableEvent::ResetPolicy::MANUAL, 739 WaitableEvent::ResetPolicy::MANUAL,
680 WaitableEvent::InitialState::NOT_SIGNALED); 740 WaitableEvent::InitialState::NOT_SIGNALED);
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
713 reinterpret_cast<const void*>(&TargetThread::CallWithAlloca)) 773 reinterpret_cast<const void*>(&TargetThread::CallWithAlloca))
714 << " was not found in stack:\n" 774 << " was not found in stack:\n"
715 << FormatSampleForDiagnosticOutput(sample, profile.modules); 775 << FormatSampleForDiagnosticOutput(sample, profile.modules);
716 776
717 // These frames should be adjacent on the stack. 777 // These frames should be adjacent on the stack.
718 EXPECT_EQ(1, alloca_frame - end_frame) 778 EXPECT_EQ(1, alloca_frame - end_frame)
719 << "Stack:\n" 779 << "Stack:\n"
720 << FormatSampleForDiagnosticOutput(sample, profile.modules); 780 << FormatSampleForDiagnosticOutput(sample, profile.modules);
721 } 781 }
722 782
723 // Checks that the fire-and-forget interface works.
724 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED)
725 #define MAYBE_StartAndRunAsync StartAndRunAsync
726 #else
727 #define MAYBE_StartAndRunAsync DISABLED_StartAndRunAsync
728 #endif
729 TEST(StackSamplingProfilerTest, MAYBE_StartAndRunAsync) {
730 // StartAndRunAsync requires the caller to have a message loop.
731 MessageLoop message_loop;
732
733 SamplingParams params;
734 params.samples_per_burst = 1;
735
736 CallStackProfiles profiles;
737 WithTargetThread([&params, &profiles](PlatformThreadId target_thread_id) {
738 WaitableEvent sampling_thread_completed(
739 WaitableEvent::ResetPolicy::AUTOMATIC,
740 WaitableEvent::InitialState::NOT_SIGNALED);
741 const StackSamplingProfiler::CompletedCallback callback =
742 Bind(&SaveProfilesAndSignalEvent, Unretained(&profiles),
743 Unretained(&sampling_thread_completed));
744 StackSamplingProfiler::StartAndRunAsync(target_thread_id, params, callback);
745 RunLoop().RunUntilIdle();
746 sampling_thread_completed.Wait();
747 });
748
749 ASSERT_EQ(1u, profiles.size());
750 }
751
752 // Checks that the expected number of profiles and samples are present in the 783 // Checks that the expected number of profiles and samples are present in the
753 // call stack profiles produced. 784 // call stack profiles produced.
754 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED) 785 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED)
755 #define MAYBE_MultipleProfilesAndSamples MultipleProfilesAndSamples 786 #define MAYBE_MultipleProfilesAndSamples MultipleProfilesAndSamples
756 #else 787 #else
757 #define MAYBE_MultipleProfilesAndSamples DISABLED_MultipleProfilesAndSamples 788 #define MAYBE_MultipleProfilesAndSamples DISABLED_MultipleProfilesAndSamples
758 #endif 789 #endif
759 TEST(StackSamplingProfilerTest, MAYBE_MultipleProfilesAndSamples) { 790 TEST_F(StackSamplingProfilerTest, MAYBE_MultipleProfilesAndSamples) {
760 SamplingParams params; 791 SamplingParams params;
761 params.burst_interval = params.sampling_interval = 792 params.burst_interval = params.sampling_interval =
762 TimeDelta::FromMilliseconds(0); 793 TimeDelta::FromMilliseconds(0);
763 params.bursts = 2; 794 params.bursts = 2;
764 params.samples_per_burst = 3; 795 params.samples_per_burst = 3;
765 796
766 std::vector<CallStackProfile> profiles; 797 std::vector<CallStackProfile> profiles;
767 CaptureProfiles(params, AVeryLongTimeDelta(), &profiles); 798 CaptureProfiles(params, AVeryLongTimeDelta(), &profiles);
768 799
769 ASSERT_EQ(2u, profiles.size()); 800 ASSERT_EQ(2u, profiles.size());
770 EXPECT_EQ(3u, profiles[0].samples.size()); 801 EXPECT_EQ(3u, profiles[0].samples.size());
771 EXPECT_EQ(3u, profiles[1].samples.size()); 802 EXPECT_EQ(3u, profiles[1].samples.size());
772 } 803 }
773 804
805 // Checks that a profiler can stop/destruct without ever having started.
806 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED)
807 #define MAYBE_StopWithoutStarting StopWithoutStarting
808 #else
809 #define MAYBE_StopWithoutStarting DISABLED_StopWithoutStarting
810 #endif
811 TEST_F(StackSamplingProfilerTest, MAYBE_StopWithoutStarting) {
812 WithTargetThread([](PlatformThreadId target_thread_id) {
813 SamplingParams params;
814 params.sampling_interval = TimeDelta::FromMilliseconds(0);
815 params.samples_per_burst = 1;
816
817 CallStackProfiles profiles;
818 WaitableEvent sampling_completed(WaitableEvent::ResetPolicy::MANUAL,
819 WaitableEvent::InitialState::NOT_SIGNALED);
820 const StackSamplingProfiler::CompletedCallback callback =
821 Bind(&SaveProfilesAndSignalEvent, Unretained(&profiles),
822 Unretained(&sampling_completed));
823 StackSamplingProfiler profiler(target_thread_id, params, callback);
824
825 profiler.Stop(); // Constructed but never started.
826 EXPECT_FALSE(sampling_completed.IsSignaled());
827 });
828 }
829
830 // Checks that its okay to stop a profiler before it finishes even when the
831 // sampling thread continues to run.
832 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED)
833 #define MAYBE_StopSafely StopSafely
834 #else
835 #define MAYBE_StopSafely DISABLED_StopSafely
836 #endif
837 TEST_F(StackSamplingProfilerTest, MAYBE_StopSafely) {
838 // Test delegate that counts samples.
839 class SampleRecordedCounter : public NativeStackSamplerTestDelegate {
840 public:
841 SampleRecordedCounter() {}
842
843 void OnPreStackWalk() override {
844 AutoLock lock(lock_);
845 ++count_;
846 }
847
848 size_t Get() {
849 AutoLock lock(lock_);
850 return count_;
851 }
852
853 private:
854 Lock lock_;
855 size_t count_ = 0;
856 };
857
858 WithTargetThread([](PlatformThreadId target_thread_id) {
859 std::vector<SamplingParams> params(2);
860
861 // Providing an initial delay makes it more likely that both will be
862 // scheduled before either starts to run. Once started, samples will
863 // run ordered by their scheduled, interleaved times regardless of
864 // whatever interval the thread wakes up.
865 params[0].initial_delay = TimeDelta::FromMilliseconds(10);
866 params[0].sampling_interval = TimeDelta::FromMilliseconds(1);
867 params[0].samples_per_burst = 100000;
868
869 params[1].initial_delay = TimeDelta::FromMilliseconds(10);
870 params[1].sampling_interval = TimeDelta::FromMilliseconds(1);
871 params[1].samples_per_burst = 100000;
872
873 std::vector<CallStackProfiles> profiles;
874 std::vector<std::unique_ptr<NativeStackSamplerTestDelegate>>
875 samples_recorded;
876 std::vector<std::unique_ptr<WaitableEvent>> sampling_completed;
877 std::vector<std::unique_ptr<StackSamplingProfiler>> profilers;
878 for (size_t i = 0; i < params.size(); ++i)
879 samples_recorded.push_back(MakeUnique<SampleRecordedCounter>());
880 CreateProfilers(target_thread_id, params, &samples_recorded, &profiles,
881 &profilers, &sampling_completed);
882
883 profilers[0]->Start();
884 profilers[1]->Start();
885
886 // Wait for both to start accumulating samples. Using a WaitableEvent is
887 // possible but gets complicated later on because there's no way of knowing
888 // if 0 or 1 additional sample will be taken after Stop() and thus no way
889 // of knowing how many Wait() calls to make on it.
890 while (
891 static_cast<SampleRecordedCounter*>(samples_recorded[0].get())->Get() ==
892 0 ||
893 static_cast<SampleRecordedCounter*>(samples_recorded[1].get())->Get() ==
894 0)
895 PlatformThread::Sleep(TimeDelta::FromMilliseconds(1));
896
897 // Ensure that the first sampler can be safely stopped while the second
898 // continues to run. The stopped first profiler will still have a
899 // PerformCollectionTask pending that will do nothing when executed because
900 // the collection will have been removed by Stop().
901 profilers[0]->Stop();
902 sampling_completed[0]->Wait();
903 size_t count0 =
904 static_cast<SampleRecordedCounter*>(samples_recorded[0].get())->Get();
905 size_t count1 =
906 static_cast<SampleRecordedCounter*>(samples_recorded[1].get())->Get();
907
908 // Waiting for the second sampler to collect a couple samples ensures that
909 // the pending PerformCollectionTask for the first has executed because
910 // tasks are always ordered by their next scheduled time.
911 while (
912 static_cast<SampleRecordedCounter*>(samples_recorded[1].get())->Get() <
913 count1 + 2)
914 PlatformThread::Sleep(TimeDelta::FromMilliseconds(1));
915
916 // Ensure that the first profiler didn't do anything since it was stopped.
917 EXPECT_EQ(
918 count0,
919 static_cast<SampleRecordedCounter*>(samples_recorded[0].get())->Get());
920 });
921 }
922
774 // Checks that no call stack profiles are captured if the profiling is stopped 923 // Checks that no call stack profiles are captured if the profiling is stopped
775 // during the initial delay. 924 // during the initial delay.
776 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED) 925 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED)
777 #define MAYBE_StopDuringInitialDelay StopDuringInitialDelay 926 #define MAYBE_StopDuringInitialDelay StopDuringInitialDelay
778 #else 927 #else
779 #define MAYBE_StopDuringInitialDelay DISABLED_StopDuringInitialDelay 928 #define MAYBE_StopDuringInitialDelay DISABLED_StopDuringInitialDelay
780 #endif 929 #endif
781 TEST(StackSamplingProfilerTest, MAYBE_StopDuringInitialDelay) { 930 TEST_F(StackSamplingProfilerTest, MAYBE_StopDuringInitialDelay) {
782 SamplingParams params; 931 SamplingParams params;
783 params.initial_delay = TimeDelta::FromSeconds(60); 932 params.initial_delay = TimeDelta::FromSeconds(60);
784 933
785 std::vector<CallStackProfile> profiles; 934 std::vector<CallStackProfile> profiles;
786 CaptureProfiles(params, TimeDelta::FromMilliseconds(0), &profiles); 935 CaptureProfiles(params, TimeDelta::FromMilliseconds(0), &profiles);
787 936
788 EXPECT_TRUE(profiles.empty()); 937 EXPECT_TRUE(profiles.empty());
789 } 938 }
790 939
791 // Checks that the single completed call stack profile is captured if the 940 // Checks that the single completed call stack profile is captured if the
792 // profiling is stopped between bursts. 941 // profiling is stopped between bursts.
793 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED) 942 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED)
794 #define MAYBE_StopDuringInterBurstInterval StopDuringInterBurstInterval 943 #define MAYBE_StopDuringInterBurstInterval StopDuringInterBurstInterval
795 #else 944 #else
796 #define MAYBE_StopDuringInterBurstInterval DISABLED_StopDuringInterBurstInterval 945 #define MAYBE_StopDuringInterBurstInterval DISABLED_StopDuringInterBurstInterval
797 #endif 946 #endif
798 TEST(StackSamplingProfilerTest, MAYBE_StopDuringInterBurstInterval) { 947 TEST_F(StackSamplingProfilerTest, MAYBE_StopDuringInterBurstInterval) {
799 SamplingParams params; 948 SamplingParams params;
800 params.sampling_interval = TimeDelta::FromMilliseconds(0); 949 params.sampling_interval = TimeDelta::FromMilliseconds(0);
801 params.burst_interval = TimeDelta::FromSeconds(60); 950 params.burst_interval = TimeDelta::FromSeconds(60);
802 params.bursts = 2; 951 params.bursts = 2;
803 params.samples_per_burst = 1; 952 params.samples_per_burst = 1;
804 953
805 std::vector<CallStackProfile> profiles; 954 std::vector<CallStackProfile> profiles;
806 CaptureProfiles(params, TimeDelta::FromMilliseconds(50), &profiles); 955 CaptureProfiles(params, TimeDelta::FromMilliseconds(50), &profiles);
807 956
808 ASSERT_EQ(1u, profiles.size()); 957 ASSERT_EQ(1u, profiles.size());
809 EXPECT_EQ(1u, profiles[0].samples.size()); 958 EXPECT_EQ(1u, profiles[0].samples.size());
810 } 959 }
811 960
812 // Checks that incomplete call stack profiles are captured. 961 // Checks that tasks can be stopped before completion and incomplete call stack
962 // profiles are captured.
813 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED) 963 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED)
814 #define MAYBE_StopDuringInterSampleInterval StopDuringInterSampleInterval 964 #define MAYBE_StopDuringInterSampleInterval StopDuringInterSampleInterval
815 #else 965 #else
816 #define MAYBE_StopDuringInterSampleInterval \ 966 #define MAYBE_StopDuringInterSampleInterval \
817 DISABLED_StopDuringInterSampleInterval 967 DISABLED_StopDuringInterSampleInterval
818 #endif 968 #endif
819 TEST(StackSamplingProfilerTest, MAYBE_StopDuringInterSampleInterval) { 969 TEST_F(StackSamplingProfilerTest, MAYBE_StopDuringInterSampleInterval) {
820 SamplingParams params; 970 // Test delegate that counts samples.
821 params.sampling_interval = TimeDelta::FromSeconds(60); 971 class SampleRecordedCounter : public NativeStackSamplerTestDelegate {
822 params.samples_per_burst = 2; 972 public:
973 SampleRecordedCounter() {}
823 974
824 std::vector<CallStackProfile> profiles; 975 void OnPreStackWalk() override {
825 CaptureProfiles(params, TimeDelta::FromMilliseconds(50), &profiles); 976 AutoLock lock(lock_);
977 ++count_;
978 }
826 979
827 ASSERT_EQ(1u, profiles.size()); 980 size_t Get() {
828 EXPECT_EQ(1u, profiles[0].samples.size()); 981 AutoLock lock(lock_);
982 return count_;
983 }
984
985 private:
986 Lock lock_;
987 size_t count_ = 0;
988 };
989
990 WithTargetThread([](PlatformThreadId target_thread_id) {
991 std::vector<SamplingParams> params(1);
992
993 params[0].sampling_interval = TimeDelta::FromMilliseconds(1);
994 params[0].samples_per_burst = 100000;
995
996 std::vector<CallStackProfiles> profiles;
997 std::vector<std::unique_ptr<NativeStackSamplerTestDelegate>>
998 samples_recorded;
999 std::vector<std::unique_ptr<WaitableEvent>> sampling_completed;
1000 std::vector<std::unique_ptr<StackSamplingProfiler>> profilers;
1001 for (size_t i = 0; i < params.size(); ++i)
1002 samples_recorded.push_back(MakeUnique<SampleRecordedCounter>());
1003 CreateProfilers(target_thread_id, params, &samples_recorded, &profiles,
1004 &profilers, &sampling_completed);
1005
1006 profilers[0]->Start();
1007
1008 // Wait for profiler to start accumulating samples.
1009 while (
Mike Wittman 2017/03/31 01:38:22 This test would be simpler and easier to understan
bcwhite 2017/03/31 13:57:56 Done.
1010 static_cast<SampleRecordedCounter*>(samples_recorded[0].get())->Get() ==
1011 0)
1012 PlatformThread::Sleep(TimeDelta::FromMilliseconds(1));
1013
1014 // Ensure that it can stop safely.
1015 profilers[0]->Stop();
1016 sampling_completed[0]->Wait();
1017
1018 ASSERT_EQ(1u, profiles[0].size());
1019 EXPECT_EQ(
1020 static_cast<SampleRecordedCounter*>(samples_recorded[0].get())->Get(),
1021 profiles[0][0].samples.size());
1022 });
829 } 1023 }
830 1024
831 // Checks that we can destroy the profiler while profiling. 1025 // Checks that we can destroy the profiler while profiling.
832 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED) 1026 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED)
833 #define MAYBE_DestroyProfilerWhileProfiling DestroyProfilerWhileProfiling 1027 #define MAYBE_DestroyProfilerWhileProfiling DestroyProfilerWhileProfiling
834 #else 1028 #else
835 #define MAYBE_DestroyProfilerWhileProfiling \ 1029 #define MAYBE_DestroyProfilerWhileProfiling \
836 DISABLED_DestroyProfilerWhileProfiling 1030 DISABLED_DestroyProfilerWhileProfiling
837 #endif 1031 #endif
838 TEST(StackSamplingProfilerTest, MAYBE_DestroyProfilerWhileProfiling) { 1032 TEST_F(StackSamplingProfilerTest, MAYBE_DestroyProfilerWhileProfiling) {
839 SamplingParams params; 1033 SamplingParams params;
840 params.sampling_interval = TimeDelta::FromMilliseconds(10); 1034 params.sampling_interval = TimeDelta::FromMilliseconds(10);
841 1035
842 CallStackProfiles profiles; 1036 CallStackProfiles profiles;
843 WithTargetThread([&params, &profiles](PlatformThreadId target_thread_id) { 1037 WithTargetThread([&params, &profiles](PlatformThreadId target_thread_id) {
844 std::unique_ptr<StackSamplingProfiler> profiler; 1038 std::unique_ptr<StackSamplingProfiler> profiler;
845 profiler.reset(new StackSamplingProfiler( 1039 profiler.reset(new StackSamplingProfiler(
846 target_thread_id, params, Bind(&SaveProfiles, Unretained(&profiles)))); 1040 target_thread_id, params, Bind(&SaveProfiles, Unretained(&profiles))));
847 profiler->Start(); 1041 profiler->Start();
848 profiler.reset(); 1042 profiler.reset();
849 1043
850 // Wait longer than a sample interval to catch any use-after-free actions by 1044 // Wait longer than a sample interval to catch any use-after-free actions by
851 // the profiler thread. 1045 // the profiler thread.
852 PlatformThread::Sleep(TimeDelta::FromMilliseconds(50)); 1046 PlatformThread::Sleep(TimeDelta::FromMilliseconds(50));
853 }); 1047 });
854 } 1048 }
855 1049
856 // Checks that the same profiler may be run multiple times. 1050 // Checks that the same profiler may be run multiple times.
857 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED) 1051 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED)
858 #define MAYBE_CanRunMultipleTimes CanRunMultipleTimes 1052 #define MAYBE_CanRunMultipleTimes CanRunMultipleTimes
859 #else 1053 #else
860 #define MAYBE_CanRunMultipleTimes DISABLED_CanRunMultipleTimes 1054 #define MAYBE_CanRunMultipleTimes DISABLED_CanRunMultipleTimes
861 #endif 1055 #endif
862 TEST(StackSamplingProfilerTest, MAYBE_CanRunMultipleTimes) { 1056 TEST_F(StackSamplingProfilerTest, MAYBE_CanRunMultipleTimes) {
1057 WithTargetThread([](PlatformThreadId target_thread_id) {
1058 SamplingParams params;
1059 params.sampling_interval = TimeDelta::FromMilliseconds(0);
1060 params.samples_per_burst = 1;
1061
1062 CallStackProfiles profiles;
1063 WaitableEvent sampling_completed(WaitableEvent::ResetPolicy::MANUAL,
1064 WaitableEvent::InitialState::NOT_SIGNALED);
1065 const StackSamplingProfiler::CompletedCallback callback =
1066 Bind(&SaveProfilesAndSignalEvent, Unretained(&profiles),
1067 Unretained(&sampling_completed));
1068 StackSamplingProfiler profiler(target_thread_id, params, callback);
1069
1070 // Just start and stop to execute code paths.
1071 profiler.Start();
1072 profiler.Stop();
1073 sampling_completed.Wait();
1074
1075 // Ensure a second request will run and not block.
1076 sampling_completed.Reset();
1077 profiles.clear();
1078 profiler.Start();
1079 sampling_completed.Wait();
1080 profiler.Stop();
1081 ASSERT_EQ(1u, profiles.size());
1082 });
1083 }
1084
1085 // Checks that the different profilers may be run.
1086 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED)
1087 #define MAYBE_CanRunMultipleProfilers CanRunMultipleProfilers
1088 #else
1089 #define MAYBE_CanRunMultipleProfilers DISABLED_CanRunMultipleProfilers
1090 #endif
1091 TEST_F(StackSamplingProfilerTest, MAYBE_CanRunMultipleProfilers) {
863 SamplingParams params; 1092 SamplingParams params;
864 params.sampling_interval = TimeDelta::FromMilliseconds(0); 1093 params.sampling_interval = TimeDelta::FromMilliseconds(0);
865 params.samples_per_burst = 1; 1094 params.samples_per_burst = 1;
866 1095
867 std::vector<CallStackProfile> profiles; 1096 std::vector<CallStackProfile> profiles;
868 CaptureProfiles(params, AVeryLongTimeDelta(), &profiles); 1097 CaptureProfiles(params, AVeryLongTimeDelta(), &profiles);
869 ASSERT_EQ(1u, profiles.size()); 1098 ASSERT_EQ(1u, profiles.size());
870 1099
871 profiles.clear(); 1100 profiles.clear();
872 CaptureProfiles(params, AVeryLongTimeDelta(), &profiles); 1101 CaptureProfiles(params, AVeryLongTimeDelta(), &profiles);
873 ASSERT_EQ(1u, profiles.size()); 1102 ASSERT_EQ(1u, profiles.size());
874 } 1103 }
875 1104
876 // Checks that requests to start profiling while another profile is taking place 1105 // Checks that a sampler can be started while another is running.
877 // are ignored. 1106 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED)
878 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED) 1107 #define MAYBE_MultipleStart MultipleStart
879 #define MAYBE_ConcurrentProfiling ConcurrentProfiling 1108 #else
880 #else 1109 #define MAYBE_MultipleStart DISABLED_MultipleStart
881 #define MAYBE_ConcurrentProfiling DISABLED_ConcurrentProfiling 1110 #endif
882 #endif 1111 TEST_F(StackSamplingProfilerTest, MAYBE_MultipleStart) {
883 TEST(StackSamplingProfilerTest, MAYBE_ConcurrentProfiling) { 1112 WithTargetThread([](PlatformThreadId target_thread_id) {
884 WithTargetThread([](PlatformThreadId target_thread_id) { 1113 std::vector<SamplingParams> params(2);
885 SamplingParams params[2]; 1114
1115 params[0].initial_delay = AVeryLongTimeDelta();
1116 params[0].samples_per_burst = 1;
1117
1118 params[1].sampling_interval = TimeDelta::FromMilliseconds(1);
1119 params[1].samples_per_burst = 1;
1120
1121 std::vector<CallStackProfiles> profiles;
1122 std::vector<std::unique_ptr<WaitableEvent>> sampling_completed;
1123 std::vector<std::unique_ptr<StackSamplingProfiler>> profilers;
1124 CreateProfilers(target_thread_id, params, nullptr, &profiles, &profilers,
1125 &sampling_completed);
1126
1127 profilers[0]->Start();
1128 profilers[1]->Start();
1129 sampling_completed[1]->Wait();
1130 EXPECT_EQ(1u, profiles[1].size());
1131 });
1132 }
1133
1134 // Checks that the sampling thread can shut down.
1135 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED)
1136 #define MAYBE_SamplerIdleShutdown SamplerIdleShutdown
1137 #else
1138 #define MAYBE_SamplerIdleShutdown DISABLED_SamplerIdleShutdown
1139 #endif
1140 TEST_F(StackSamplingProfilerTest, MAYBE_SamplerIdleShutdown) {
1141 SamplingParams params;
1142 params.sampling_interval = TimeDelta::FromMilliseconds(0);
1143 params.samples_per_burst = 1;
1144
1145 std::vector<CallStackProfile> profiles;
1146 CaptureProfiles(params, AVeryLongTimeDelta(), &profiles);
1147 ASSERT_EQ(1u, profiles.size());
1148
1149 // Capture thread should still be running at this point.
1150 ASSERT_TRUE(StackSamplingProfiler::TestAPI::IsSamplingThreadRunning());
1151
1152 // Initiate an "idle" shutdown and ensure it happens. Idle-shutdown was
1153 // disabled above so the test will fail due to a timeout if it does not
1154 // exit.
1155 StackSamplingProfiler::TestAPI::PerformSamplingThreadIdleShutdown(false);
1156
1157 // While the shutdown has been initiated, the actual exit of the thread still
1158 // happens asynchronously. Watch until the thread actually exits. This test
1159 // will time-out in the case of failure.
1160 while (StackSamplingProfiler::TestAPI::IsSamplingThreadRunning())
1161 PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(1));
1162 }
1163
1164 // Checks that additional requests will restart a stopped profiler.
1165 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED)
1166 #define MAYBE_WillRestartSamplerAfterIdleShutdown \
1167 WillRestartSamplerAfterIdleShutdown
1168 #else
1169 #define MAYBE_WillRestartSamplerAfterIdleShutdown \
1170 DISABLED_WillRestartSamplerAfterIdleShutdown
1171 #endif
1172 TEST_F(StackSamplingProfilerTest, MAYBE_WillRestartSamplerAfterIdleShutdown) {
1173 SamplingParams params;
1174 params.sampling_interval = TimeDelta::FromMilliseconds(0);
1175 params.samples_per_burst = 1;
1176
1177 std::vector<CallStackProfile> profiles;
1178 CaptureProfiles(params, AVeryLongTimeDelta(), &profiles);
1179 ASSERT_EQ(1u, profiles.size());
1180
1181 // Capture thread should still be running at this point.
1182 ASSERT_TRUE(StackSamplingProfiler::TestAPI::IsSamplingThreadRunning());
1183
1184 // Post a ShutdownTask on the sampling thread which, when executed, will
1185 // mark the thread as EXITING and begin shut down of the thread.
1186 StackSamplingProfiler::TestAPI::PerformSamplingThreadIdleShutdown(false);
1187
1188 // Ensure another capture will start the sampling thread and run.
1189 profiles.clear();
1190 CaptureProfiles(params, AVeryLongTimeDelta(), &profiles);
1191 ASSERT_EQ(1u, profiles.size());
1192 EXPECT_TRUE(StackSamplingProfiler::TestAPI::IsSamplingThreadRunning());
1193 }
1194
1195 // Checks that it's safe to stop a task after it's completed and the sampling
1196 // thread has shut-down for being idle.
1197 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED)
1198 #define MAYBE_StopAfterIdleShutdown StopAfterIdleShutdown
1199 #else
1200 #define MAYBE_StopAfterIdleShutdown DISABLED_StopAfterIdleShutdown
1201 #endif
1202 TEST_F(StackSamplingProfilerTest, MAYBE_StopAfterIdleShutdown) {
1203 WithTargetThread([](PlatformThreadId target_thread_id) {
1204 std::vector<SamplingParams> params(1);
1205
1206 params[0].sampling_interval = TimeDelta::FromMilliseconds(1);
1207 params[0].samples_per_burst = 1;
1208
1209 std::vector<CallStackProfiles> profiles;
1210 std::vector<std::unique_ptr<WaitableEvent>> sampling_completed;
1211 std::vector<std::unique_ptr<StackSamplingProfiler>> profilers;
1212 CreateProfilers(target_thread_id, params, nullptr, &profiles, &profilers,
1213 &sampling_completed);
1214
1215 profilers[0]->Start();
1216 sampling_completed[0]->Wait();
1217
1218 // Capture thread should still be running at this point.
1219 ASSERT_TRUE(StackSamplingProfiler::TestAPI::IsSamplingThreadRunning());
1220
1221 // Perform an idle shutdown.
1222 StackSamplingProfiler::TestAPI::PerformSamplingThreadIdleShutdown(false);
1223
1224 // Stop should be safe though its impossible to know at this moment if the
1225 // sampling thread has completely exited or will just "stop soon".
1226 profilers[0]->Stop();
1227 });
1228 }
1229
1230 // Checks that profilers can run both before and after the sampling thread has
1231 // started.
1232 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED)
1233 #define MAYBE_ProfileBeforeAndAfterSamplingThreadRunning \
1234 ProfileBeforeAndAfterSamplingThreadRunning
1235 #else
1236 #define MAYBE_ProfileBeforeAndAfterSamplingThreadRunning \
1237 DISABLED_ProfileBeforeAndAfterSamplingThreadRunning
1238 #endif
1239 TEST_F(StackSamplingProfilerTest,
1240 MAYBE_ProfileBeforeAndAfterSamplingThreadRunning) {
1241 WithTargetThread([](PlatformThreadId target_thread_id) {
1242 std::vector<SamplingParams> params(2);
1243
1244 params[0].initial_delay = AVeryLongTimeDelta();
1245 params[0].sampling_interval = TimeDelta::FromMilliseconds(1);
1246 params[0].samples_per_burst = 1;
1247
1248 params[1].initial_delay = TimeDelta::FromMilliseconds(0);
1249 params[1].sampling_interval = TimeDelta::FromMilliseconds(1);
1250 params[1].samples_per_burst = 1;
1251
1252 std::vector<CallStackProfiles> profiles;
1253 std::vector<std::unique_ptr<WaitableEvent>> sampling_completed;
1254 std::vector<std::unique_ptr<StackSamplingProfiler>> profilers;
1255 CreateProfilers(target_thread_id, params, nullptr, &profiles, &profilers,
1256 &sampling_completed);
1257
1258 // First profiler is started when there has never been a sampling thread.
1259 EXPECT_FALSE(StackSamplingProfiler::TestAPI::IsSamplingThreadRunning());
1260 profilers[0]->Start();
1261 // Second profiler is started when sampling thread is already running.
1262 EXPECT_TRUE(StackSamplingProfiler::TestAPI::IsSamplingThreadRunning());
1263 profilers[1]->Start();
1264
1265 // Only the second profiler should finish before test times out.
1266 size_t completed_profiler = WaitForSamplingComplete(&sampling_completed);
1267 EXPECT_EQ(1U, completed_profiler);
1268 });
1269 }
1270
1271 // Checks that an idle-shutdown task will abort if a new profiler starts
1272 // between when it was posted and when it runs.
1273 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED)
1274 #define MAYBE_IdleShutdownAbort IdleShutdownAbort
1275 #else
1276 #define MAYBE_IdleShutdownAbort DISABLED_IdleShutdownAbort
1277 #endif
1278 TEST_F(StackSamplingProfilerTest, MAYBE_IdleShutdownAbort) {
1279 WithTargetThread([](PlatformThreadId target_thread_id) {
1280 std::vector<SamplingParams> params(1);
1281
1282 params[0].sampling_interval = TimeDelta::FromMilliseconds(1);
1283 params[0].samples_per_burst = 1;
1284
1285 std::vector<CallStackProfiles> profiles;
1286 std::vector<std::unique_ptr<WaitableEvent>> sampling_completed;
1287 std::vector<std::unique_ptr<StackSamplingProfiler>> profilers;
1288 CreateProfilers(target_thread_id, params, nullptr, &profiles, &profilers,
1289 &sampling_completed);
1290
1291 profilers[0]->Start();
1292 sampling_completed[0]->Wait();
1293
1294 // Perform an idle shutdown but simulate that a new capture is started
1295 // before it can actually run.
1296 StackSamplingProfiler::TestAPI::PerformSamplingThreadIdleShutdown(true);
1297
1298 // Though the shutdown-task has been executed, any actual exit of the
1299 // thread is asynchronous so there is no way to detect that *didn't* exit
1300 // except to wait a reasonable amount of time and then check. Since the
1301 // thread was just running ("perform" blocked until it was), it should
1302 // finish almost immediately and without any waiting for tasks or events.
1303 PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(200));
1304 EXPECT_TRUE(StackSamplingProfiler::TestAPI::IsSamplingThreadRunning());
1305 });
1306 }
1307
1308 // Checks that synchronized multiple sampling requests execute in parallel.
1309 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED)
1310 #define MAYBE_ConcurrentProfiling_InSync ConcurrentProfiling_InSync
1311 #else
1312 #define MAYBE_ConcurrentProfiling_InSync DISABLED_ConcurrentProfiling_InSync
1313 #endif
1314 TEST_F(StackSamplingProfilerTest, MAYBE_ConcurrentProfiling_InSync) {
1315 WithTargetThread([](PlatformThreadId target_thread_id) {
1316 std::vector<SamplingParams> params(2);
1317
1318 // Providing an initial delay makes it more likely that both will be
1319 // scheduled before either starts to run. Once started, samples will
1320 // run ordered by their scheduled, interleaved times regardless of
1321 // whatever interval the thread wakes up. Thus, total execution time
1322 // will be 10ms (delay) + 10x1ms (sampling) + 1/2 timer minimum interval.
886 params[0].initial_delay = TimeDelta::FromMilliseconds(10); 1323 params[0].initial_delay = TimeDelta::FromMilliseconds(10);
887 params[0].sampling_interval = TimeDelta::FromMilliseconds(0); 1324 params[0].sampling_interval = TimeDelta::FromMilliseconds(1);
888 params[0].samples_per_burst = 1; 1325 params[0].samples_per_burst = 9;
889 1326
890 params[1].sampling_interval = TimeDelta::FromMilliseconds(0); 1327 params[1].initial_delay = TimeDelta::FromMilliseconds(11);
891 params[1].samples_per_burst = 1; 1328 params[1].sampling_interval = TimeDelta::FromMilliseconds(1);
892 1329 params[1].samples_per_burst = 8;
893 CallStackProfiles profiles[2]; 1330
894 std::vector<std::unique_ptr<WaitableEvent>> sampling_completed(2); 1331 std::vector<CallStackProfiles> profiles;
895 std::vector<std::unique_ptr<StackSamplingProfiler>> profiler(2); 1332 std::vector<std::unique_ptr<WaitableEvent>> sampling_completed;
896 for (int i = 0; i < 2; ++i) { 1333 std::vector<std::unique_ptr<StackSamplingProfiler>> profilers;
897 sampling_completed[i] = 1334 CreateProfilers(target_thread_id, params, nullptr, &profiles, &profilers,
898 MakeUnique<WaitableEvent>(WaitableEvent::ResetPolicy::AUTOMATIC, 1335 &sampling_completed);
899 WaitableEvent::InitialState::NOT_SIGNALED); 1336
900 const StackSamplingProfiler::CompletedCallback callback = 1337 profilers[0]->Start();
901 Bind(&SaveProfilesAndSignalEvent, Unretained(&profiles[i]), 1338 profilers[1]->Start();
902 Unretained(sampling_completed[i].get())); 1339
903 profiler[i] = MakeUnique<StackSamplingProfiler>(target_thread_id,
904 params[i], callback);
905 }
906
907 profiler[0]->Start();
908 profiler[1]->Start();
909
910 std::vector<WaitableEvent*> sampling_completed_rawptrs(
911 sampling_completed.size());
912 std::transform(
913 sampling_completed.begin(), sampling_completed.end(),
914 sampling_completed_rawptrs.begin(),
915 [](const std::unique_ptr<WaitableEvent>& elem) { return elem.get(); });
916 // Wait for one profiler to finish. 1340 // Wait for one profiler to finish.
917 size_t completed_profiler = 1341 size_t completed_profiler = WaitForSamplingComplete(&sampling_completed);
918 WaitableEvent::WaitMany(sampling_completed_rawptrs.data(), 2); 1342 ASSERT_EQ(1u, profiles[completed_profiler].size());
1343
1344 size_t other_profiler = 1 - completed_profiler;
1345 // Wait for the other profiler to finish.
1346 sampling_completed[other_profiler]->Wait();
1347 ASSERT_EQ(1u, profiles[other_profiler].size());
1348
1349 // Ensure each got the correct number of samples.
1350 EXPECT_EQ(9u, profiles[0][0].samples.size());
1351 EXPECT_EQ(8u, profiles[1][0].samples.size());
1352 });
1353 }
1354
1355 // Checks that several mixed sampling requests execute in parallel.
1356 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED)
1357 #define MAYBE_ConcurrentProfiling_Mixed ConcurrentProfiling_Mixed
1358 #else
1359 #define MAYBE_ConcurrentProfiling_Mixed DISABLED_ConcurrentProfiling_Mixed
1360 #endif
1361 TEST_F(StackSamplingProfilerTest, MAYBE_ConcurrentProfiling_Mixed) {
1362 WithTargetThread([](PlatformThreadId target_thread_id) {
1363 std::vector<SamplingParams> params(3);
1364
1365 params[0].initial_delay = TimeDelta::FromMilliseconds(8);
1366 params[0].sampling_interval = TimeDelta::FromMilliseconds(4);
1367 params[0].samples_per_burst = 10;
1368
1369 params[1].initial_delay = TimeDelta::FromMilliseconds(9);
1370 params[1].sampling_interval = TimeDelta::FromMilliseconds(3);
1371 params[1].samples_per_burst = 10;
1372
1373 params[2].initial_delay = TimeDelta::FromMilliseconds(10);
1374 params[2].sampling_interval = TimeDelta::FromMilliseconds(2);
1375 params[2].samples_per_burst = 10;
1376
1377 std::vector<CallStackProfiles> profiles;
1378 std::vector<std::unique_ptr<WaitableEvent>> sampling_completed;
1379 std::vector<std::unique_ptr<StackSamplingProfiler>> profilers;
1380 CreateProfilers(target_thread_id, params, nullptr, &profiles, &profilers,
1381 &sampling_completed);
1382
1383 for (size_t i = 0; i < profilers.size(); ++i)
1384 profilers[i]->Start();
1385
1386 // Wait for one profiler to finish.
1387 size_t completed_profiler = WaitForSamplingComplete(&sampling_completed);
919 EXPECT_EQ(1u, profiles[completed_profiler].size()); 1388 EXPECT_EQ(1u, profiles[completed_profiler].size());
920 1389 // Stop and destroy all profilers, always in the same order. Don't crash.
921 size_t other_profiler = 1 - completed_profiler; 1390 for (size_t i = 0; i < profilers.size(); ++i)
922 // Give the other profiler a chance to run and observe that it hasn't. 1391 profilers[i]->Stop();
923 EXPECT_FALSE(sampling_completed[other_profiler]->TimedWait( 1392 for (size_t i = 0; i < profilers.size(); ++i)
924 TimeDelta::FromMilliseconds(25))); 1393 profilers[i].reset();
925 1394 });
926 // Start the other profiler again and it should run. 1395 }
927 profiler[other_profiler]->Start(); 1396
928 sampling_completed[other_profiler]->Wait();
929 EXPECT_EQ(1u, profiles[other_profiler].size());
930 });
931 }
932
933 // Checks that a stack that runs through another library produces a stack with 1397 // Checks that a stack that runs through another library produces a stack with
934 // the expected functions. 1398 // the expected functions.
935 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED) 1399 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED)
936 #define MAYBE_OtherLibrary OtherLibrary 1400 #define MAYBE_OtherLibrary OtherLibrary
937 #else 1401 #else
938 #define MAYBE_OtherLibrary DISABLED_OtherLibrary 1402 #define MAYBE_OtherLibrary DISABLED_OtherLibrary
939 #endif 1403 #endif
940 TEST(StackSamplingProfilerTest, MAYBE_OtherLibrary) { 1404 TEST_F(StackSamplingProfilerTest, MAYBE_OtherLibrary) {
941 SamplingParams params; 1405 SamplingParams params;
942 params.sampling_interval = TimeDelta::FromMilliseconds(0); 1406 params.sampling_interval = TimeDelta::FromMilliseconds(0);
943 params.samples_per_burst = 1; 1407 params.samples_per_burst = 1;
944 1408
945 std::vector<CallStackProfile> profiles; 1409 std::vector<CallStackProfile> profiles;
946 { 1410 {
947 ScopedNativeLibrary other_library(LoadOtherLibrary()); 1411 ScopedNativeLibrary other_library(LoadOtherLibrary());
948 WithTargetThread( 1412 WithTargetThread(
949 [&params, &profiles](PlatformThreadId target_thread_id) { 1413 [&params, &profiles](PlatformThreadId target_thread_id) {
950 WaitableEvent sampling_thread_completed( 1414 WaitableEvent sampling_thread_completed(
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
1001 << "Stack:\n" << FormatSampleForDiagnosticOutput(sample, profile.modules); 1465 << "Stack:\n" << FormatSampleForDiagnosticOutput(sample, profile.modules);
1002 } 1466 }
1003 1467
1004 // Checks that a stack that runs through a library that is unloading produces a 1468 // Checks that a stack that runs through a library that is unloading produces a
1005 // stack, and doesn't crash. 1469 // stack, and doesn't crash.
1006 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED) 1470 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED)
1007 #define MAYBE_UnloadingLibrary UnloadingLibrary 1471 #define MAYBE_UnloadingLibrary UnloadingLibrary
1008 #else 1472 #else
1009 #define MAYBE_UnloadingLibrary DISABLED_UnloadingLibrary 1473 #define MAYBE_UnloadingLibrary DISABLED_UnloadingLibrary
1010 #endif 1474 #endif
1011 TEST(StackSamplingProfilerTest, MAYBE_UnloadingLibrary) { 1475 TEST_F(StackSamplingProfilerTest, MAYBE_UnloadingLibrary) {
1012 TestLibraryUnload(false); 1476 TestLibraryUnload(false);
1013 } 1477 }
1014 1478
1015 // Checks that a stack that runs through a library that has been unloaded 1479 // Checks that a stack that runs through a library that has been unloaded
1016 // produces a stack, and doesn't crash. 1480 // produces a stack, and doesn't crash.
1017 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED) 1481 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED)
1018 #define MAYBE_UnloadedLibrary UnloadedLibrary 1482 #define MAYBE_UnloadedLibrary UnloadedLibrary
1019 #else 1483 #else
1020 #define MAYBE_UnloadedLibrary DISABLED_UnloadedLibrary 1484 #define MAYBE_UnloadedLibrary DISABLED_UnloadedLibrary
1021 #endif 1485 #endif
1022 TEST(StackSamplingProfilerTest, MAYBE_UnloadedLibrary) { 1486 TEST_F(StackSamplingProfilerTest, MAYBE_UnloadedLibrary) {
1023 TestLibraryUnload(true); 1487 TestLibraryUnload(true);
1024 } 1488 }
1025 1489
1490 // Checks that different threads can be sampled in parallel.
1491 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED)
1492 #define MAYBE_MultipleSampledThreads MultipleSampledThreads
1493 #else
1494 #define MAYBE_MultipleSampledThreads DISABLED_MultipleSampledThreads
1495 #endif
1496 TEST_F(StackSamplingProfilerTest, MAYBE_MultipleSampledThreads) {
1497 // Create target threads. The extra parethesis around the StackConfiguration
1498 // call are to avoid the most-vexing-parse problem.
1499 TargetThread target_thread1((StackConfiguration(StackConfiguration::NORMAL)));
1500 TargetThread target_thread2((StackConfiguration(StackConfiguration::NORMAL)));
1501 PlatformThreadHandle target_thread_handle1, target_thread_handle2;
1502 EXPECT_TRUE(
1503 PlatformThread::Create(0, &target_thread1, &target_thread_handle1));
1504 EXPECT_TRUE(
1505 PlatformThread::Create(0, &target_thread2, &target_thread_handle2));
1506 target_thread1.WaitForThreadStart();
1507 target_thread2.WaitForThreadStart();
1508
1509 // Providing an initial delay makes it more likely that both will be
1510 // scheduled before either starts to run. Once started, samples will
1511 // run ordered by their scheduled, interleaved times regardless of
1512 // whatever interval the thread wakes up.
1513 SamplingParams params1, params2;
1514 params1.initial_delay = TimeDelta::FromMilliseconds(10);
1515 params1.sampling_interval = TimeDelta::FromMilliseconds(1);
1516 params1.samples_per_burst = 9;
1517 params2.initial_delay = TimeDelta::FromMilliseconds(10);
1518 params2.sampling_interval = TimeDelta::FromMilliseconds(1);
1519 params2.samples_per_burst = 8;
1520
1521 std::vector<CallStackProfile> profiles1, profiles2;
1522
1523 WaitableEvent sampling_thread_completed1(
1524 WaitableEvent::ResetPolicy::MANUAL,
1525 WaitableEvent::InitialState::NOT_SIGNALED);
1526 const StackSamplingProfiler::CompletedCallback callback1 =
1527 Bind(&SaveProfilesAndSignalEvent, Unretained(&profiles1),
1528 Unretained(&sampling_thread_completed1));
1529 StackSamplingProfiler profiler1(target_thread1.id(), params1, callback1);
1530
1531 WaitableEvent sampling_thread_completed2(
1532 WaitableEvent::ResetPolicy::MANUAL,
1533 WaitableEvent::InitialState::NOT_SIGNALED);
1534 const StackSamplingProfiler::CompletedCallback callback2 =
1535 Bind(&SaveProfilesAndSignalEvent, Unretained(&profiles2),
1536 Unretained(&sampling_thread_completed2));
1537 StackSamplingProfiler profiler2(target_thread2.id(), params2, callback2);
1538
1539 // Finally the real work.
1540 profiler1.Start();
1541 profiler2.Start();
1542 sampling_thread_completed1.Wait();
1543 sampling_thread_completed2.Wait();
1544 ASSERT_EQ(1u, profiles1.size());
1545 EXPECT_EQ(9u, profiles1[0].samples.size());
1546 ASSERT_EQ(1u, profiles2.size());
1547 EXPECT_EQ(8u, profiles2[0].samples.size());
1548
1549 target_thread1.SignalThreadToFinish();
1550 target_thread2.SignalThreadToFinish();
1551 PlatformThread::Join(target_thread_handle1);
1552 PlatformThread::Join(target_thread_handle2);
1553 }
1554
1555 // A simple thread that runs a profiler on another thread.
1556 class ProfilerThread : public SimpleThread {
1557 public:
1558 ProfilerThread(const std::string& name,
1559 PlatformThreadId thread_id,
1560 const SamplingParams& params)
1561 : SimpleThread(name, Options()),
1562 run_(WaitableEvent::ResetPolicy::MANUAL,
1563 WaitableEvent::InitialState::NOT_SIGNALED),
1564 completed_(WaitableEvent::ResetPolicy::MANUAL,
1565 WaitableEvent::InitialState::NOT_SIGNALED),
1566 profiler_(thread_id,
1567 params,
1568 Bind(&SaveProfilesAndSignalEvent,
1569 Unretained(&profiles_),
1570 Unretained(&completed_))) {}
1571
1572 void Run() override {
1573 run_.Wait();
1574 profiler_.Start();
1575 }
1576
1577 void Go() { run_.Signal(); }
1578
1579 void Wait() { completed_.Wait(); }
1580
1581 CallStackProfiles& profiles() { return profiles_; }
1582
1583 private:
1584 WaitableEvent run_;
1585
1586 CallStackProfiles profiles_;
1587 WaitableEvent completed_;
1588 StackSamplingProfiler profiler_;
1589 };
1590
1591 // Checks that different threads can run samplers in parallel.
1592 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED)
1593 #define MAYBE_MultipleProfilerThreads MultipleProfilerThreads
1594 #else
1595 #define MAYBE_MultipleProfilerThreads DISABLED_MultipleProfilerThreads
1596 #endif
1597 TEST_F(StackSamplingProfilerTest, MAYBE_MultipleProfilerThreads) {
1598 WithTargetThread([](PlatformThreadId target_thread_id) {
1599 // Providing an initial delay makes it more likely that both will be
1600 // scheduled before either starts to run. Once started, samples will
1601 // run ordered by their scheduled, interleaved times regardless of
1602 // whatever interval the thread wakes up.
1603 SamplingParams params1, params2;
1604 params1.initial_delay = TimeDelta::FromMilliseconds(10);
1605 params1.sampling_interval = TimeDelta::FromMilliseconds(1);
1606 params1.samples_per_burst = 9;
1607 params2.initial_delay = TimeDelta::FromMilliseconds(10);
1608 params2.sampling_interval = TimeDelta::FromMilliseconds(1);
1609 params2.samples_per_burst = 8;
1610
1611 // Start the profiler threads and give them a moment to get going.
1612 ProfilerThread profiler1("profiler_thread1", target_thread_id, params1);
1613 ProfilerThread profiler2("profiler_thread2", target_thread_id, params2);
1614 profiler1.Start();
1615 profiler2.Start();
1616 PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(10));
1617
1618 // This will (approximately) synchronize the two threads.
1619 profiler1.Go();
1620 profiler2.Go();
1621
1622 // Wait for them both to finish and validate collection.
1623 profiler1.Wait();
1624 profiler2.Wait();
1625 ASSERT_EQ(1u, profiler1.profiles().size());
1626 EXPECT_EQ(9u, profiler1.profiles()[0].samples.size());
1627 ASSERT_EQ(1u, profiler2.profiles().size());
1628 EXPECT_EQ(8u, profiler2.profiles()[0].samples.size());
1629
1630 profiler1.Join();
1631 profiler2.Join();
1632 });
1633 }
1634
1026 } // namespace base 1635 } // namespace base
OLDNEW
« no previous file with comments | « base/profiler/stack_sampling_profiler.cc ('k') | base/threading/thread_restrictions.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698