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

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

Issue 2554123002: Support parallel captures from the StackSamplingProfiler. (Closed)
Patch Set: addressed review comments by wittman Created 3 years, 10 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
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>
(...skipping 426 matching lines...) Expand 10 before | Expand all | Expand 10 after
437 // asynchronous library loading has completed before walking the stack. If 437 // asynchronous library loading has completed before walking the stack. If
438 // false, the unloading may still be occurring during the stack walk. 438 // false, the unloading may still be occurring during the stack walk.
439 void TestLibraryUnload(bool wait_until_unloaded) { 439 void TestLibraryUnload(bool wait_until_unloaded) {
440 // Test delegate that supports intervening between the copying of the stack 440 // Test delegate that supports intervening between the copying of the stack
441 // and the walking of the stack. 441 // and the walking of the stack.
442 class StackCopiedSignaler : public NativeStackSamplerTestDelegate { 442 class StackCopiedSignaler : public NativeStackSamplerTestDelegate {
443 public: 443 public:
444 StackCopiedSignaler(WaitableEvent* stack_copied, 444 StackCopiedSignaler(WaitableEvent* stack_copied,
445 WaitableEvent* start_stack_walk, 445 WaitableEvent* start_stack_walk,
446 bool wait_to_walk_stack) 446 bool wait_to_walk_stack)
447 : stack_copied_(stack_copied), start_stack_walk_(start_stack_walk), 447 : stack_copied_(stack_copied),
448 wait_to_walk_stack_(wait_to_walk_stack) { 448 start_stack_walk_(start_stack_walk),
449 } 449 wait_to_walk_stack_(wait_to_walk_stack) {}
450 450
451 void OnPreStackWalk() override { 451 void OnPreStackWalk() override {
452 stack_copied_->Signal(); 452 stack_copied_->Signal();
453 if (wait_to_walk_stack_) 453 if (wait_to_walk_stack_)
454 start_stack_walk_->Wait(); 454 start_stack_walk_->Wait();
455 } 455 }
456 456
457 private: 457 private:
458 WaitableEvent* const stack_copied_; 458 WaitableEvent* const stack_copied_;
459 WaitableEvent* const start_stack_walk_; 459 WaitableEvent* const start_stack_walk_;
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after
713 reinterpret_cast<const void*>(&TargetThread::CallWithAlloca)) 713 reinterpret_cast<const void*>(&TargetThread::CallWithAlloca))
714 << " was not found in stack:\n" 714 << " was not found in stack:\n"
715 << FormatSampleForDiagnosticOutput(sample, profile.modules); 715 << FormatSampleForDiagnosticOutput(sample, profile.modules);
716 716
717 // These frames should be adjacent on the stack. 717 // These frames should be adjacent on the stack.
718 EXPECT_EQ(1, alloca_frame - end_frame) 718 EXPECT_EQ(1, alloca_frame - end_frame)
719 << "Stack:\n" 719 << "Stack:\n"
720 << FormatSampleForDiagnosticOutput(sample, profile.modules); 720 << FormatSampleForDiagnosticOutput(sample, profile.modules);
721 } 721 }
722 722
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 723 // Checks that the expected number of profiles and samples are present in the
753 // call stack profiles produced. 724 // call stack profiles produced.
754 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED) 725 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED)
755 #define MAYBE_MultipleProfilesAndSamples MultipleProfilesAndSamples 726 #define MAYBE_MultipleProfilesAndSamples MultipleProfilesAndSamples
756 #else 727 #else
757 #define MAYBE_MultipleProfilesAndSamples DISABLED_MultipleProfilesAndSamples 728 #define MAYBE_MultipleProfilesAndSamples DISABLED_MultipleProfilesAndSamples
758 #endif 729 #endif
759 TEST(StackSamplingProfilerTest, MAYBE_MultipleProfilesAndSamples) { 730 TEST(StackSamplingProfilerTest, MAYBE_MultipleProfilesAndSamples) {
760 SamplingParams params; 731 SamplingParams params;
761 params.burst_interval = params.sampling_interval = 732 params.burst_interval = params.sampling_interval =
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
853 }); 824 });
854 } 825 }
855 826
856 // Checks that the same profiler may be run multiple times. 827 // Checks that the same profiler may be run multiple times.
857 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED) 828 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED)
858 #define MAYBE_CanRunMultipleTimes CanRunMultipleTimes 829 #define MAYBE_CanRunMultipleTimes CanRunMultipleTimes
859 #else 830 #else
860 #define MAYBE_CanRunMultipleTimes DISABLED_CanRunMultipleTimes 831 #define MAYBE_CanRunMultipleTimes DISABLED_CanRunMultipleTimes
861 #endif 832 #endif
862 TEST(StackSamplingProfilerTest, MAYBE_CanRunMultipleTimes) { 833 TEST(StackSamplingProfilerTest, MAYBE_CanRunMultipleTimes) {
834 StackSamplingProfiler::TestAPI::SetSamplingThreadIdleShutdownTime(0);
835
863 SamplingParams params; 836 SamplingParams params;
864 params.sampling_interval = TimeDelta::FromMilliseconds(0); 837 params.sampling_interval = TimeDelta::FromMilliseconds(0);
865 params.samples_per_burst = 1; 838 params.samples_per_burst = 1;
866 839
867 std::vector<CallStackProfile> profiles; 840 std::vector<CallStackProfile> profiles;
868 CaptureProfiles(params, AVeryLongTimeDelta(), &profiles); 841 CaptureProfiles(params, AVeryLongTimeDelta(), &profiles);
869 ASSERT_EQ(1u, profiles.size()); 842 ASSERT_EQ(1u, profiles.size());
870 843
871 profiles.clear(); 844 profiles.clear();
872 CaptureProfiles(params, AVeryLongTimeDelta(), &profiles); 845 CaptureProfiles(params, AVeryLongTimeDelta(), &profiles);
873 ASSERT_EQ(1u, profiles.size()); 846 ASSERT_EQ(1u, profiles.size());
847
848 // Capture thread should still be running at this point.
Mike Wittman 2017/02/22 03:06:48 The shutdown and restart behavior should be broken
bcwhite 2017/02/22 14:32:51 Done.
849 ASSERT_TRUE(StackSamplingProfiler::TestAPI::IsSamplingThreadRunning());
850
851 // Initiate an "idle" shutdown. The task will be run immediately but on
852 // another thread so wait for it to complete.
853 StackSamplingProfiler::TestAPI::InitiateSamplingThreadIdleShutdown();
854 while (StackSamplingProfiler::TestAPI::IsSamplingThreadRunning())
855 PlatformThread::YieldCurrentThread();
856
857 // Ensure another capture will start the sampling thread and run.
858 profiles.clear();
859 CaptureProfiles(params, AVeryLongTimeDelta(), &profiles);
860 ASSERT_EQ(1u, profiles.size());
861 EXPECT_TRUE(StackSamplingProfiler::TestAPI::IsSamplingThreadRunning());
874 } 862 }
875 863
876 // Checks that requests to start profiling while another profile is taking place 864 // Checks that multiple sampling requests execute in parallel.
877 // are ignored.
878 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED) 865 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED)
879 #define MAYBE_ConcurrentProfiling ConcurrentProfiling 866 #define MAYBE_ConcurrentProfiling ConcurrentProfiling
Mike Wittman 2017/02/22 03:06:48 I think we should test different interleavings of
bcwhite 2017/02/22 14:32:51 Done.
880 #else 867 #else
881 #define MAYBE_ConcurrentProfiling DISABLED_ConcurrentProfiling 868 #define MAYBE_ConcurrentProfiling DISABLED_ConcurrentProfiling
882 #endif 869 #endif
883 TEST(StackSamplingProfilerTest, MAYBE_ConcurrentProfiling) { 870 TEST(StackSamplingProfilerTest, MAYBE_ConcurrentProfiling) {
884 WithTargetThread([](PlatformThreadId target_thread_id) { 871 WithTargetThread([](PlatformThreadId target_thread_id) {
885 SamplingParams params[2]; 872 SamplingParams params[2];
886 params[0].initial_delay = TimeDelta::FromMilliseconds(10); 873 params[0].initial_delay = TimeDelta::FromMilliseconds(10);
887 params[0].sampling_interval = TimeDelta::FromMilliseconds(0); 874 params[0].sampling_interval = TimeDelta::FromMilliseconds(1);
888 params[0].samples_per_burst = 1; 875 params[0].samples_per_burst = 10;
889 876
890 params[1].sampling_interval = TimeDelta::FromMilliseconds(0); 877 params[0].initial_delay = TimeDelta::FromMilliseconds(10);
891 params[1].samples_per_burst = 1; 878 params[1].sampling_interval = TimeDelta::FromMilliseconds(1);
879 params[1].samples_per_burst = 10;
892 880
893 CallStackProfiles profiles[2]; 881 CallStackProfiles profiles[2];
894 std::vector<std::unique_ptr<WaitableEvent>> sampling_completed(2); 882 std::vector<std::unique_ptr<WaitableEvent>> sampling_completed(2);
895 std::vector<std::unique_ptr<StackSamplingProfiler>> profiler(2); 883 std::vector<std::unique_ptr<StackSamplingProfiler>> profiler(2);
896 for (int i = 0; i < 2; ++i) { 884 for (int i = 0; i < 2; ++i) {
897 sampling_completed[i] = 885 sampling_completed[i] =
898 MakeUnique<WaitableEvent>(WaitableEvent::ResetPolicy::AUTOMATIC, 886 MakeUnique<WaitableEvent>(WaitableEvent::ResetPolicy::AUTOMATIC,
899 WaitableEvent::InitialState::NOT_SIGNALED); 887 WaitableEvent::InitialState::NOT_SIGNALED);
900 const StackSamplingProfiler::CompletedCallback callback = 888 const StackSamplingProfiler::CompletedCallback callback =
901 Bind(&SaveProfilesAndSignalEvent, Unretained(&profiles[i]), 889 Bind(&SaveProfilesAndSignalEvent, Unretained(&profiles[i]),
(...skipping 10 matching lines...) Expand all
912 std::transform( 900 std::transform(
913 sampling_completed.begin(), sampling_completed.end(), 901 sampling_completed.begin(), sampling_completed.end(),
914 sampling_completed_rawptrs.begin(), 902 sampling_completed_rawptrs.begin(),
915 [](const std::unique_ptr<WaitableEvent>& elem) { return elem.get(); }); 903 [](const std::unique_ptr<WaitableEvent>& elem) { return elem.get(); });
916 // Wait for one profiler to finish. 904 // Wait for one profiler to finish.
917 size_t completed_profiler = 905 size_t completed_profiler =
918 WaitableEvent::WaitMany(sampling_completed_rawptrs.data(), 2); 906 WaitableEvent::WaitMany(sampling_completed_rawptrs.data(), 2);
919 EXPECT_EQ(1u, profiles[completed_profiler].size()); 907 EXPECT_EQ(1u, profiles[completed_profiler].size());
920 908
921 size_t other_profiler = 1 - completed_profiler; 909 size_t other_profiler = 1 - completed_profiler;
922 // Give the other profiler a chance to run and observe that it hasn't. 910 // Give the other profiler a chance to finish and verify it does so.
923 EXPECT_FALSE(sampling_completed[other_profiler]->TimedWait( 911 EXPECT_TRUE(sampling_completed[other_profiler]->TimedWait(
924 TimeDelta::FromMilliseconds(25))); 912 TimeDelta::FromMilliseconds(250)));
925
926 // Start the other profiler again and it should run.
927 profiler[other_profiler]->Start();
928 sampling_completed[other_profiler]->Wait();
929 EXPECT_EQ(1u, profiles[other_profiler].size());
930 }); 913 });
931 } 914 }
932 915
933 // Checks that a stack that runs through another library produces a stack with 916 // Checks that a stack that runs through another library produces a stack with
934 // the expected functions. 917 // the expected functions.
935 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED) 918 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED)
936 #define MAYBE_OtherLibrary OtherLibrary 919 #define MAYBE_OtherLibrary OtherLibrary
937 #else 920 #else
938 #define MAYBE_OtherLibrary DISABLED_OtherLibrary 921 #define MAYBE_OtherLibrary DISABLED_OtherLibrary
939 #endif 922 #endif
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
1017 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED) 1000 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED)
1018 #define MAYBE_UnloadedLibrary UnloadedLibrary 1001 #define MAYBE_UnloadedLibrary UnloadedLibrary
1019 #else 1002 #else
1020 #define MAYBE_UnloadedLibrary DISABLED_UnloadedLibrary 1003 #define MAYBE_UnloadedLibrary DISABLED_UnloadedLibrary
1021 #endif 1004 #endif
1022 TEST(StackSamplingProfilerTest, MAYBE_UnloadedLibrary) { 1005 TEST(StackSamplingProfilerTest, MAYBE_UnloadedLibrary) {
1023 TestLibraryUnload(true); 1006 TestLibraryUnload(true);
1024 } 1007 }
1025 1008
1026 } // namespace base 1009 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698