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

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

Issue 2554123002: Support parallel captures from the StackSamplingProfiler. (Closed)
Patch Set: more test improvements 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->at(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 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
580 } // namespace 634 } // namespace
581 635
582 // Checks that the basic expected information is present in a sampled call stack 636 // Checks that the basic expected information is present in a sampled call stack
583 // profile. 637 // profile.
584 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED) 638 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED)
585 #define MAYBE_Basic Basic 639 #define MAYBE_Basic Basic
586 #else 640 #else
587 #define MAYBE_Basic DISABLED_Basic 641 #define MAYBE_Basic DISABLED_Basic
588 #endif 642 #endif
589 TEST(StackSamplingProfilerTest, MAYBE_Basic) { 643 TEST(StackSamplingProfilerTest, MAYBE_Basic) {
644 StackSamplingProfiler::TestAPI::Reset();
590 StackSamplingProfiler::ResetAnnotationsForTesting(); 645 StackSamplingProfiler::ResetAnnotationsForTesting();
591 646
592 SamplingParams params; 647 SamplingParams params;
593 params.sampling_interval = TimeDelta::FromMilliseconds(0); 648 params.sampling_interval = TimeDelta::FromMilliseconds(0);
594 params.samples_per_burst = 1; 649 params.samples_per_burst = 1;
595 650
596 std::vector<CallStackProfile> profiles; 651 std::vector<CallStackProfile> profiles;
597 CaptureProfiles(params, AVeryLongTimeDelta(), &profiles); 652 CaptureProfiles(params, AVeryLongTimeDelta(), &profiles);
598 653
599 // Check that the profile and samples sizes are correct, and the module 654 // Check that the profile and samples sizes are correct, and the module
(...skipping 25 matching lines...) Expand all
625 EXPECT_EQ(executable_path, profile.modules[loc->module_index].filename); 680 EXPECT_EQ(executable_path, profile.modules[loc->module_index].filename);
626 } 681 }
627 682
628 // Checks that annotations are recorded in samples. 683 // Checks that annotations are recorded in samples.
629 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED) 684 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED)
630 #define MAYBE_Annotations Annotations 685 #define MAYBE_Annotations Annotations
631 #else 686 #else
632 #define MAYBE_Annotations DISABLED_Annotations 687 #define MAYBE_Annotations DISABLED_Annotations
633 #endif 688 #endif
634 TEST(StackSamplingProfilerTest, MAYBE_Annotations) { 689 TEST(StackSamplingProfilerTest, MAYBE_Annotations) {
690 StackSamplingProfiler::TestAPI::Reset();
635 StackSamplingProfiler::ResetAnnotationsForTesting(); 691 StackSamplingProfiler::ResetAnnotationsForTesting();
636 692
637 SamplingParams params; 693 SamplingParams params;
638 params.sampling_interval = TimeDelta::FromMilliseconds(0); 694 params.sampling_interval = TimeDelta::FromMilliseconds(0);
639 params.samples_per_burst = 1; 695 params.samples_per_burst = 1;
640 696
641 // Check that a run picks up annotations. 697 // Check that a run picks up annotations.
642 StackSamplingProfiler::SetProcessMilestone(1); 698 StackSamplingProfiler::SetProcessMilestone(1);
643 std::vector<CallStackProfile> profiles1; 699 std::vector<CallStackProfile> profiles1;
644 CaptureProfiles(params, AVeryLongTimeDelta(), &profiles1); 700 CaptureProfiles(params, AVeryLongTimeDelta(), &profiles1);
(...skipping 16 matching lines...) Expand all
661 } 717 }
662 718
663 // Checks that the profiler handles stacks containing dynamically-allocated 719 // Checks that the profiler handles stacks containing dynamically-allocated
664 // stack memory. 720 // stack memory.
665 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED) 721 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED)
666 #define MAYBE_Alloca Alloca 722 #define MAYBE_Alloca Alloca
667 #else 723 #else
668 #define MAYBE_Alloca DISABLED_Alloca 724 #define MAYBE_Alloca DISABLED_Alloca
669 #endif 725 #endif
670 TEST(StackSamplingProfilerTest, MAYBE_Alloca) { 726 TEST(StackSamplingProfilerTest, MAYBE_Alloca) {
727 StackSamplingProfiler::TestAPI::Reset();
728
671 SamplingParams params; 729 SamplingParams params;
672 params.sampling_interval = TimeDelta::FromMilliseconds(0); 730 params.sampling_interval = TimeDelta::FromMilliseconds(0);
673 params.samples_per_burst = 1; 731 params.samples_per_burst = 1;
674 732
675 std::vector<CallStackProfile> profiles; 733 std::vector<CallStackProfile> profiles;
676 WithTargetThread( 734 WithTargetThread(
677 [&params, &profiles](PlatformThreadId target_thread_id) { 735 [&params, &profiles](PlatformThreadId target_thread_id) {
678 WaitableEvent sampling_thread_completed( 736 WaitableEvent sampling_thread_completed(
679 WaitableEvent::ResetPolicy::MANUAL, 737 WaitableEvent::ResetPolicy::MANUAL,
680 WaitableEvent::InitialState::NOT_SIGNALED); 738 WaitableEvent::InitialState::NOT_SIGNALED);
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
713 reinterpret_cast<const void*>(&TargetThread::CallWithAlloca)) 771 reinterpret_cast<const void*>(&TargetThread::CallWithAlloca))
714 << " was not found in stack:\n" 772 << " was not found in stack:\n"
715 << FormatSampleForDiagnosticOutput(sample, profile.modules); 773 << FormatSampleForDiagnosticOutput(sample, profile.modules);
716 774
717 // These frames should be adjacent on the stack. 775 // These frames should be adjacent on the stack.
718 EXPECT_EQ(1, alloca_frame - end_frame) 776 EXPECT_EQ(1, alloca_frame - end_frame)
719 << "Stack:\n" 777 << "Stack:\n"
720 << FormatSampleForDiagnosticOutput(sample, profile.modules); 778 << FormatSampleForDiagnosticOutput(sample, profile.modules);
721 } 779 }
722 780
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 781 // Checks that the expected number of profiles and samples are present in the
753 // call stack profiles produced. 782 // call stack profiles produced.
754 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED) 783 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED)
755 #define MAYBE_MultipleProfilesAndSamples MultipleProfilesAndSamples 784 #define MAYBE_MultipleProfilesAndSamples MultipleProfilesAndSamples
756 #else 785 #else
757 #define MAYBE_MultipleProfilesAndSamples DISABLED_MultipleProfilesAndSamples 786 #define MAYBE_MultipleProfilesAndSamples DISABLED_MultipleProfilesAndSamples
758 #endif 787 #endif
759 TEST(StackSamplingProfilerTest, MAYBE_MultipleProfilesAndSamples) { 788 TEST(StackSamplingProfilerTest, MAYBE_MultipleProfilesAndSamples) {
789 StackSamplingProfiler::TestAPI::Reset();
790
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(StackSamplingProfilerTest, MAYBE_StopWithoutStarting) {
812 StackSamplingProfiler::TestAPI::Reset();
813
814 WithTargetThread([](PlatformThreadId target_thread_id) {
815 SamplingParams params;
816 params.sampling_interval = TimeDelta::FromMilliseconds(0);
817 params.samples_per_burst = 1;
818
819 CallStackProfiles profiles;
820 WaitableEvent sampling_completed(WaitableEvent::ResetPolicy::MANUAL,
821 WaitableEvent::InitialState::NOT_SIGNALED);
822 const StackSamplingProfiler::CompletedCallback callback =
823 Bind(&SaveProfilesAndSignalEvent, Unretained(&profiles),
824 Unretained(&sampling_completed));
825 StackSamplingProfiler profiler(target_thread_id, params, callback);
826
827 profiler.Stop(); // Constructed but never started.
828 EXPECT_FALSE(sampling_completed.IsSignaled());
829 });
830 }
831
832 // Checks that its okay to stop a profiler before it finishes.
833 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED)
834 #define MAYBE_StopSafely StopSafely
835 #else
836 #define MAYBE_StopSafely DISABLED_StopSafely
837 #endif
838 TEST(StackSamplingProfilerTest, MAYBE_StopSafely) {
839 StackSamplingProfiler::TestAPI::Reset();
840 StackSamplingProfiler::TestAPI::DisableIdleShutdown();
841
842 // Test delegate that counts samples.
843 class SampleRecordedCounter : public NativeStackSamplerTestDelegate {
844 public:
845 SampleRecordedCounter() {}
846
847 void OnPreStackWalk() override {
848 AutoLock lock(lock_);
849 ++count_;
850 }
851
852 int Get() {
853 AutoLock lock(lock_);
854 return count_;
855 }
856
857 private:
858 Lock lock_;
859 int count_ = 0;
860 };
861
862 WithTargetThread([](PlatformThreadId target_thread_id) {
863 std::vector<SamplingParams> params(2);
864
865 // Providing an initial delay makes it more likely that both will be
866 // scheduled before either starts to run. Once started, samples will
867 // run ordered by their scheduled, interleaved times regardless of
868 // whatever interval the thread wakes up.
869 params[0].initial_delay = TimeDelta::FromMilliseconds(10);
870 params[0].sampling_interval = TimeDelta::FromMilliseconds(1);
871 params[0].samples_per_burst = 100000;
872
873 params[1].initial_delay = TimeDelta::FromMilliseconds(10);
874 params[1].sampling_interval = TimeDelta::FromMilliseconds(1);
875 params[1].samples_per_burst = 100000;
876
877 std::vector<CallStackProfiles> profiles;
878 std::vector<std::unique_ptr<SampleRecordedCounter>> samples_recorded;
879 std::vector<std::unique_ptr<WaitableEvent>> sampling_completed;
880 std::vector<std::unique_ptr<StackSamplingProfiler>> profilers;
881 for (size_t i = 0; i < params.size(); ++i)
882 samples_recorded.push_back(MakeUnique<SampleRecordedCounter>());
883 CreateProfilers(
884 target_thread_id, params,
885 reinterpret_cast<
886 std::vector<std::unique_ptr<NativeStackSamplerTestDelegate>>*>(
887 &samples_recorded),
888 &profiles, &profilers, &sampling_completed);
889
890 profilers[0]->Start();
891 profilers[1]->Start();
892
893 // Wait for both to start accumulating samples. Using a WaitableEvent is
894 // possible but gets complicated later on because there's no way of knowing
895 // if 0 or 1 additional sample will be taken after Stop() and thus no way
896 // of knowing how many Wait() calls to make on it.
897 while (samples_recorded[0]->Get() == 0 || samples_recorded[1]->Get() == 0)
898 PlatformThread::Sleep(TimeDelta::FromMilliseconds(1));
899
900 // Ensure that the first sampler can be safely stopped while the second
901 // continues to run. The stopped first profiler will still have a
902 // PerformCollectionTask pending that will do nothing when executed because
903 // the collection will have been removed by Stop().
904 profilers[0]->Stop();
905 sampling_completed[0]->Wait();
906 int count0 = samples_recorded[0]->Get();
907 int count1 = samples_recorded[1]->Get();
908
909 // Waiting for the second sampler to collect a couple samples ensures that
910 // the pending PerformCollectionTask for the first has executed because
911 // tasks are always ordered by their next scheduled time.
912 while (samples_recorded[1]->Get() < count1 + 2)
913 PlatformThread::Sleep(TimeDelta::FromMilliseconds(1));
914
915 // Ensure that the first profiler didn't do anything since it was stopped.
916 EXPECT_EQ(count0, samples_recorded[0]->Get());
917 });
918 }
919
774 // Checks that no call stack profiles are captured if the profiling is stopped 920 // Checks that no call stack profiles are captured if the profiling is stopped
775 // during the initial delay. 921 // during the initial delay.
776 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED) 922 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED)
777 #define MAYBE_StopDuringInitialDelay StopDuringInitialDelay 923 #define MAYBE_StopDuringInitialDelay StopDuringInitialDelay
778 #else 924 #else
779 #define MAYBE_StopDuringInitialDelay DISABLED_StopDuringInitialDelay 925 #define MAYBE_StopDuringInitialDelay DISABLED_StopDuringInitialDelay
780 #endif 926 #endif
781 TEST(StackSamplingProfilerTest, MAYBE_StopDuringInitialDelay) { 927 TEST(StackSamplingProfilerTest, MAYBE_StopDuringInitialDelay) {
928 StackSamplingProfiler::TestAPI::Reset();
929
782 SamplingParams params; 930 SamplingParams params;
783 params.initial_delay = TimeDelta::FromSeconds(60); 931 params.initial_delay = TimeDelta::FromSeconds(60);
784 932
785 std::vector<CallStackProfile> profiles; 933 std::vector<CallStackProfile> profiles;
786 CaptureProfiles(params, TimeDelta::FromMilliseconds(0), &profiles); 934 CaptureProfiles(params, TimeDelta::FromMilliseconds(0), &profiles);
787 935
788 EXPECT_TRUE(profiles.empty()); 936 EXPECT_TRUE(profiles.empty());
789 } 937 }
790 938
791 // Checks that the single completed call stack profile is captured if the 939 // Checks that the single completed call stack profile is captured if the
792 // profiling is stopped between bursts. 940 // profiling is stopped between bursts.
793 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED) 941 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED)
794 #define MAYBE_StopDuringInterBurstInterval StopDuringInterBurstInterval 942 #define MAYBE_StopDuringInterBurstInterval StopDuringInterBurstInterval
795 #else 943 #else
796 #define MAYBE_StopDuringInterBurstInterval DISABLED_StopDuringInterBurstInterval 944 #define MAYBE_StopDuringInterBurstInterval DISABLED_StopDuringInterBurstInterval
797 #endif 945 #endif
798 TEST(StackSamplingProfilerTest, MAYBE_StopDuringInterBurstInterval) { 946 TEST(StackSamplingProfilerTest, MAYBE_StopDuringInterBurstInterval) {
947 StackSamplingProfiler::TestAPI::Reset();
948
799 SamplingParams params; 949 SamplingParams params;
800 params.sampling_interval = TimeDelta::FromMilliseconds(0); 950 params.sampling_interval = TimeDelta::FromMilliseconds(0);
801 params.burst_interval = TimeDelta::FromSeconds(60); 951 params.burst_interval = TimeDelta::FromSeconds(60);
802 params.bursts = 2; 952 params.bursts = 2;
803 params.samples_per_burst = 1; 953 params.samples_per_burst = 1;
804 954
805 std::vector<CallStackProfile> profiles; 955 std::vector<CallStackProfile> profiles;
806 CaptureProfiles(params, TimeDelta::FromMilliseconds(50), &profiles); 956 CaptureProfiles(params, TimeDelta::FromMilliseconds(50), &profiles);
807 957
808 ASSERT_EQ(1u, profiles.size()); 958 ASSERT_EQ(1u, profiles.size());
809 EXPECT_EQ(1u, profiles[0].samples.size()); 959 EXPECT_EQ(1u, profiles[0].samples.size());
810 } 960 }
811 961
812 // Checks that incomplete call stack profiles are captured. 962 // Checks that incomplete call stack 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(StackSamplingProfilerTest, MAYBE_StopDuringInterSampleInterval) {
970 StackSamplingProfiler::TestAPI::Reset();
971
820 SamplingParams params; 972 SamplingParams params;
821 params.sampling_interval = TimeDelta::FromSeconds(60); 973 params.sampling_interval = TimeDelta::FromSeconds(60);
822 params.samples_per_burst = 2; 974 params.samples_per_burst = 2;
823 975
824 std::vector<CallStackProfile> profiles; 976 std::vector<CallStackProfile> profiles;
825 CaptureProfiles(params, TimeDelta::FromMilliseconds(50), &profiles); 977 CaptureProfiles(params, TimeDelta::FromMilliseconds(50), &profiles);
826 978
827 ASSERT_EQ(1u, profiles.size()); 979 ASSERT_EQ(1u, profiles.size());
828 EXPECT_EQ(1u, profiles[0].samples.size()); 980 EXPECT_EQ(1u, profiles[0].samples.size());
829 } 981 }
830 982
831 // Checks that we can destroy the profiler while profiling. 983 // Checks that we can destroy the profiler while profiling.
832 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED) 984 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED)
833 #define MAYBE_DestroyProfilerWhileProfiling DestroyProfilerWhileProfiling 985 #define MAYBE_DestroyProfilerWhileProfiling DestroyProfilerWhileProfiling
834 #else 986 #else
835 #define MAYBE_DestroyProfilerWhileProfiling \ 987 #define MAYBE_DestroyProfilerWhileProfiling \
836 DISABLED_DestroyProfilerWhileProfiling 988 DISABLED_DestroyProfilerWhileProfiling
837 #endif 989 #endif
838 TEST(StackSamplingProfilerTest, MAYBE_DestroyProfilerWhileProfiling) { 990 TEST(StackSamplingProfilerTest, MAYBE_DestroyProfilerWhileProfiling) {
991 StackSamplingProfiler::TestAPI::Reset();
992
839 SamplingParams params; 993 SamplingParams params;
840 params.sampling_interval = TimeDelta::FromMilliseconds(10); 994 params.sampling_interval = TimeDelta::FromMilliseconds(10);
841 995
842 CallStackProfiles profiles; 996 CallStackProfiles profiles;
843 WithTargetThread([&params, &profiles](PlatformThreadId target_thread_id) { 997 WithTargetThread([&params, &profiles](PlatformThreadId target_thread_id) {
844 std::unique_ptr<StackSamplingProfiler> profiler; 998 std::unique_ptr<StackSamplingProfiler> profiler;
845 profiler.reset(new StackSamplingProfiler( 999 profiler.reset(new StackSamplingProfiler(
846 target_thread_id, params, Bind(&SaveProfiles, Unretained(&profiles)))); 1000 target_thread_id, params, Bind(&SaveProfiles, Unretained(&profiles))));
847 profiler->Start(); 1001 profiler->Start();
848 profiler.reset(); 1002 profiler.reset();
849 1003
850 // Wait longer than a sample interval to catch any use-after-free actions by 1004 // Wait longer than a sample interval to catch any use-after-free actions by
851 // the profiler thread. 1005 // the profiler thread.
852 PlatformThread::Sleep(TimeDelta::FromMilliseconds(50)); 1006 PlatformThread::Sleep(TimeDelta::FromMilliseconds(50));
853 }); 1007 });
854 } 1008 }
855 1009
856 // Checks that the same profiler may be run multiple times. 1010 // Checks that the same profiler may be run multiple times.
857 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED) 1011 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED)
858 #define MAYBE_CanRunMultipleTimes CanRunMultipleTimes 1012 #define MAYBE_CanRunMultipleTimes CanRunMultipleTimes
859 #else 1013 #else
860 #define MAYBE_CanRunMultipleTimes DISABLED_CanRunMultipleTimes 1014 #define MAYBE_CanRunMultipleTimes DISABLED_CanRunMultipleTimes
861 #endif 1015 #endif
862 TEST(StackSamplingProfilerTest, MAYBE_CanRunMultipleTimes) { 1016 TEST(StackSamplingProfilerTest, MAYBE_CanRunMultipleTimes) {
1017 StackSamplingProfiler::TestAPI::Reset();
1018 StackSamplingProfiler::TestAPI::DisableIdleShutdown();
1019
1020 WithTargetThread([](PlatformThreadId target_thread_id) {
1021 SamplingParams params;
1022 params.sampling_interval = TimeDelta::FromMilliseconds(0);
1023 params.samples_per_burst = 1;
1024
1025 CallStackProfiles profiles;
1026 WaitableEvent sampling_completed(WaitableEvent::ResetPolicy::MANUAL,
1027 WaitableEvent::InitialState::NOT_SIGNALED);
1028 const StackSamplingProfiler::CompletedCallback callback =
1029 Bind(&SaveProfilesAndSignalEvent, Unretained(&profiles),
1030 Unretained(&sampling_completed));
1031 StackSamplingProfiler profiler(target_thread_id, params, callback);
1032
1033 // Just start and stop to execute code paths.
1034 profiler.Start();
1035 profiler.Stop();
1036 sampling_completed.Wait();
1037
1038 // Ensure a second request will run and not block.
1039 sampling_completed.Reset();
1040 profiles.clear();
1041 profiler.Start();
1042 sampling_completed.Wait();
1043 profiler.Stop();
1044 ASSERT_EQ(1u, profiles.size());
1045 });
1046 }
1047
1048 // Checks that the different profilers may be run.
1049 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED)
1050 #define MAYBE_CanRunMultipleProfilers CanRunMultipleProfilers
1051 #else
1052 #define MAYBE_CanRunMultipleProfilers DISABLED_CanRunMultipleProfilers
1053 #endif
1054 TEST(StackSamplingProfilerTest, MAYBE_CanRunMultipleProfilers) {
1055 StackSamplingProfiler::TestAPI::Reset();
1056 StackSamplingProfiler::TestAPI::DisableIdleShutdown();
1057
863 SamplingParams params; 1058 SamplingParams params;
864 params.sampling_interval = TimeDelta::FromMilliseconds(0); 1059 params.sampling_interval = TimeDelta::FromMilliseconds(0);
865 params.samples_per_burst = 1; 1060 params.samples_per_burst = 1;
866 1061
867 std::vector<CallStackProfile> profiles; 1062 std::vector<CallStackProfile> profiles;
868 CaptureProfiles(params, AVeryLongTimeDelta(), &profiles); 1063 CaptureProfiles(params, AVeryLongTimeDelta(), &profiles);
869 ASSERT_EQ(1u, profiles.size()); 1064 ASSERT_EQ(1u, profiles.size());
870 1065
871 profiles.clear(); 1066 profiles.clear();
872 CaptureProfiles(params, AVeryLongTimeDelta(), &profiles); 1067 CaptureProfiles(params, AVeryLongTimeDelta(), &profiles);
873 ASSERT_EQ(1u, profiles.size()); 1068 ASSERT_EQ(1u, profiles.size());
874 } 1069 }
875 1070
876 // Checks that requests to start profiling while another profile is taking place 1071 // Checks that a sampler can be started while another is running.
877 // are ignored. 1072 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED)
878 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED) 1073 #define MAYBE_MultipleStart MultipleStart
879 #define MAYBE_ConcurrentProfiling ConcurrentProfiling 1074 #else
880 #else 1075 #define MAYBE_MultipleStart DISABLED_MultipleStart
881 #define MAYBE_ConcurrentProfiling DISABLED_ConcurrentProfiling 1076 #endif
882 #endif 1077 TEST(StackSamplingProfilerTest, MAYBE_MultipleStart) {
883 TEST(StackSamplingProfilerTest, MAYBE_ConcurrentProfiling) { 1078 StackSamplingProfiler::TestAPI::Reset();
884 WithTargetThread([](PlatformThreadId target_thread_id) { 1079 StackSamplingProfiler::TestAPI::DisableIdleShutdown();
885 SamplingParams params[2]; 1080
1081 WithTargetThread([](PlatformThreadId target_thread_id) {
1082 std::vector<SamplingParams> params(2);
1083
1084 params[0].initial_delay = AVeryLongTimeDelta();
1085 params[0].samples_per_burst = 1;
1086
1087 params[1].sampling_interval = TimeDelta::FromMilliseconds(1);
1088 params[1].samples_per_burst = 1;
1089
1090 std::vector<CallStackProfiles> profiles;
1091 std::vector<std::unique_ptr<WaitableEvent>> sampling_completed;
1092 std::vector<std::unique_ptr<StackSamplingProfiler>> profilers;
1093 CreateProfilers(target_thread_id, params, nullptr, &profiles, &profilers,
1094 &sampling_completed);
1095
1096 profilers[0]->Start();
1097 profilers[1]->Start();
1098 sampling_completed[1]->Wait();
1099 EXPECT_EQ(1u, profiles[1].size());
1100 });
1101 }
1102
1103 // Checks that the sampling thread can shut down.
1104 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED)
1105 #define MAYBE_SamplerIdleShutdown SamplerIdleShutdown
1106 #else
1107 #define MAYBE_SamplerIdleShutdown DISABLED_SamplerIdleShutdown
1108 #endif
1109 TEST(StackSamplingProfilerTest, MAYBE_SamplerIdleShutdown) {
1110 StackSamplingProfiler::TestAPI::Reset();
1111 StackSamplingProfiler::TestAPI::DisableIdleShutdown();
1112
1113 SamplingParams params;
1114 params.sampling_interval = TimeDelta::FromMilliseconds(0);
1115 params.samples_per_burst = 1;
1116
1117 std::vector<CallStackProfile> profiles;
1118 CaptureProfiles(params, AVeryLongTimeDelta(), &profiles);
1119 ASSERT_EQ(1u, profiles.size());
1120
1121 // Capture thread should still be running at this point.
1122 ASSERT_TRUE(StackSamplingProfiler::TestAPI::IsSamplingThreadRunning());
1123
1124 // Initiate an "idle" shutdown and ensure it happens. Idle-shutdown was
1125 // disabled above so the test will fail due to a timeout if it does not
1126 // exit.
1127 StackSamplingProfiler::TestAPI::PerformSamplingThreadIdleShutdown(false);
1128
1129 // While the shutdown has been initiated, the actual exit of the thread still
1130 // happens asynchronously. Watch until the thread actually exits. This test
1131 // will time-out in the case of failure.
1132 while (StackSamplingProfiler::TestAPI::IsSamplingThreadRunning())
1133 PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(1));
1134 }
1135
1136 // Checks that additional requests will restart a stopped profiler.
1137 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED)
1138 #define MAYBE_WillRestartSamplerAfterIdleShutdown \
1139 WillRestartSamplerAfterIdleShutdown
1140 #else
1141 #define MAYBE_WillRestartSamplerAfterIdleShutdown \
1142 DISABLED_WillRestartSamplerAfterIdleShutdown
1143 #endif
1144 TEST(StackSamplingProfilerTest, MAYBE_WillRestartSamplerAfterIdleShutdown) {
1145 StackSamplingProfiler::TestAPI::Reset();
1146 StackSamplingProfiler::TestAPI::DisableIdleShutdown();
1147
1148 SamplingParams params;
1149 params.sampling_interval = TimeDelta::FromMilliseconds(0);
1150 params.samples_per_burst = 1;
1151
1152 std::vector<CallStackProfile> profiles;
1153 CaptureProfiles(params, AVeryLongTimeDelta(), &profiles);
1154 ASSERT_EQ(1u, profiles.size());
1155
1156 // Capture thread should still be running at this point.
1157 ASSERT_TRUE(StackSamplingProfiler::TestAPI::IsSamplingThreadRunning());
1158
1159 // Post a ShutdownTask on the sampling thread which, when executed, will
1160 // mark the thread as EXITING and begin shut down of the thread.
1161 StackSamplingProfiler::TestAPI::PerformSamplingThreadIdleShutdown(false);
1162
1163 // Ensure another capture will start the sampling thread and run.
1164 profiles.clear();
1165 CaptureProfiles(params, AVeryLongTimeDelta(), &profiles);
1166 ASSERT_EQ(1u, profiles.size());
1167 EXPECT_TRUE(StackSamplingProfiler::TestAPI::IsSamplingThreadRunning());
1168 }
1169
1170 // Checks that it's safe to stop a task after it's completed and the sampling
1171 // thread has shut-down for being idle.
1172 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED)
1173 #define MAYBE_StopAfterIdleShutdown StopAfterIdleShutdown
1174 #else
1175 #define MAYBE_StopAfterIdleShutdown DISABLED_StopAfterIdleShutdown
1176 #endif
1177 TEST(StackSamplingProfilerTest, MAYBE_StopAfterIdleShutdown) {
1178 StackSamplingProfiler::TestAPI::Reset();
1179 StackSamplingProfiler::TestAPI::DisableIdleShutdown();
1180
1181 WithTargetThread([](PlatformThreadId target_thread_id) {
1182 std::vector<SamplingParams> params(1);
1183
1184 params[0].sampling_interval = TimeDelta::FromMilliseconds(1);
1185 params[0].samples_per_burst = 1;
1186
1187 std::vector<CallStackProfiles> profiles;
1188 std::vector<std::unique_ptr<WaitableEvent>> sampling_completed;
1189 std::vector<std::unique_ptr<StackSamplingProfiler>> profilers;
1190 CreateProfilers(target_thread_id, params, nullptr, &profiles, &profilers,
1191 &sampling_completed);
1192
1193 profilers[0]->Start();
1194 sampling_completed[0]->Wait();
1195
1196 // Capture thread should still be running at this point.
1197 ASSERT_TRUE(StackSamplingProfiler::TestAPI::IsSamplingThreadRunning());
1198
1199 // Perform an idle shutdown.
1200 StackSamplingProfiler::TestAPI::PerformSamplingThreadIdleShutdown(false);
1201
1202 // Stop should be safe though its impossible to know at this moment if the
1203 // sampling thread has completely exited or will just "stop soon".
1204 profilers[0]->Stop();
1205 });
1206 }
1207
1208 // Checks that profilers can run both before and after the sampling thread has
1209 // started.
1210 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED)
1211 #define MAYBE_ProfileBeforeAndAfterSamplingThreadRunning \
1212 ProfileBeforeAndAfterSamplingThreadRunning
1213 #else
1214 #define MAYBE_ProfileBeforeAndAfterSamplingThreadRunning \
1215 DISABLED_ProfileBeforeAndAfterSamplingThreadRunning
1216 #endif
1217 TEST(StackSamplingProfilerTest,
1218 MAYBE_ProfileBeforeAndAfterSamplingThreadRunning) {
1219 StackSamplingProfiler::TestAPI::Reset();
1220 StackSamplingProfiler::TestAPI::DisableIdleShutdown();
1221
1222 WithTargetThread([](PlatformThreadId target_thread_id) {
1223 std::vector<SamplingParams> params(2);
1224
1225 params[0].initial_delay = AVeryLongTimeDelta();
1226 params[0].sampling_interval = TimeDelta::FromMilliseconds(1);
1227 params[0].samples_per_burst = 1;
1228
1229 params[1].initial_delay = TimeDelta::FromMilliseconds(0);
1230 params[1].sampling_interval = TimeDelta::FromMilliseconds(1);
1231 params[1].samples_per_burst = 1;
1232
1233 std::vector<CallStackProfiles> profiles;
1234 std::vector<std::unique_ptr<WaitableEvent>> sampling_completed;
1235 std::vector<std::unique_ptr<StackSamplingProfiler>> profilers;
1236 CreateProfilers(target_thread_id, params, nullptr, &profiles, &profilers,
1237 &sampling_completed);
1238
1239 // First profiler is started when there has never been a sampling thread.
1240 EXPECT_FALSE(StackSamplingProfiler::TestAPI::IsSamplingThreadRunning());
1241 profilers[0]->Start();
1242 // Second profiler is started when sampling thread is already running.
1243 EXPECT_TRUE(StackSamplingProfiler::TestAPI::IsSamplingThreadRunning());
1244 profilers[1]->Start();
1245
1246 // Only the second profiler should finish before test times out.
1247 size_t completed_profiler = WaitForSamplingComplete(&sampling_completed);
1248 EXPECT_EQ(1U, completed_profiler);
1249 });
1250 }
1251
1252 // Checks that an idle-shutdown task will abort if a new profiler starts
1253 // between when it was posted and when it runs.
1254 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED)
1255 #define MAYBE_IdleShutdownAbort IdleShutdownAbort
1256 #else
1257 #define MAYBE_IdleShutdownAbort DISABLED_IdleShutdownAbort
1258 #endif
1259 TEST(StackSamplingProfilerTest, MAYBE_IdleShutdownAbort) {
1260 StackSamplingProfiler::TestAPI::Reset();
1261 StackSamplingProfiler::TestAPI::DisableIdleShutdown();
1262
1263 WithTargetThread([](PlatformThreadId target_thread_id) {
1264 std::vector<SamplingParams> params(1);
1265
1266 params[0].sampling_interval = TimeDelta::FromMilliseconds(1);
1267 params[0].samples_per_burst = 1;
1268
1269 std::vector<CallStackProfiles> profiles;
1270 std::vector<std::unique_ptr<WaitableEvent>> sampling_completed;
1271 std::vector<std::unique_ptr<StackSamplingProfiler>> profilers;
1272 CreateProfilers(target_thread_id, params, nullptr, &profiles, &profilers,
1273 &sampling_completed);
1274
1275 profilers[0]->Start();
1276 sampling_completed[0]->Wait();
1277
1278 // Perform an idle shutdown but simulate that a new capture is started
1279 // before it can actually run.
1280 StackSamplingProfiler::TestAPI::PerformSamplingThreadIdleShutdown(true);
1281
1282 // Though the shutdown-task has been executed, any actual exit of the
1283 // thread is asynchronous so there is no way to detect that *didn't* exit
1284 // except to wait a reasonable amount of time and then check. Since the
1285 // thread was just running ("perform" blocked until it was), it should
1286 // finish almost immediately and without any waiting for tasks or events.
1287 PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(200));
1288 EXPECT_TRUE(StackSamplingProfiler::TestAPI::IsSamplingThreadRunning());
1289 });
1290 }
1291
1292 // Checks that synchronized multiple sampling requests execute in parallel.
1293 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED)
1294 #define MAYBE_ConcurrentProfiling_InSync ConcurrentProfiling_InSync
1295 #else
1296 #define MAYBE_ConcurrentProfiling_InSync DISABLED_ConcurrentProfiling_InSync
1297 #endif
1298 TEST(StackSamplingProfilerTest, MAYBE_ConcurrentProfiling_InSync) {
1299 StackSamplingProfiler::TestAPI::Reset();
1300 StackSamplingProfiler::TestAPI::DisableIdleShutdown();
1301
1302 WithTargetThread([](PlatformThreadId target_thread_id) {
1303 std::vector<SamplingParams> params(2);
1304
1305 // Providing an initial delay makes it more likely that both will be
1306 // scheduled before either starts to run. Once started, samples will
1307 // run ordered by their scheduled, interleaved times regardless of
1308 // whatever interval the thread wakes up. Thus, total execution time
1309 // will be 10ms (delay) + 10x1ms (sampling) + 1/2 timer minimum interval.
886 params[0].initial_delay = TimeDelta::FromMilliseconds(10); 1310 params[0].initial_delay = TimeDelta::FromMilliseconds(10);
887 params[0].sampling_interval = TimeDelta::FromMilliseconds(0); 1311 params[0].sampling_interval = TimeDelta::FromMilliseconds(1);
888 params[0].samples_per_burst = 1; 1312 params[0].samples_per_burst = 9;
889 1313
890 params[1].sampling_interval = TimeDelta::FromMilliseconds(0); 1314 params[1].initial_delay = TimeDelta::FromMilliseconds(11);
891 params[1].samples_per_burst = 1; 1315 params[1].sampling_interval = TimeDelta::FromMilliseconds(1);
892 1316 params[1].samples_per_burst = 8;
893 CallStackProfiles profiles[2]; 1317
894 std::vector<std::unique_ptr<WaitableEvent>> sampling_completed(2); 1318 std::vector<CallStackProfiles> profiles;
895 std::vector<std::unique_ptr<StackSamplingProfiler>> profiler(2); 1319 std::vector<std::unique_ptr<WaitableEvent>> sampling_completed;
896 for (int i = 0; i < 2; ++i) { 1320 std::vector<std::unique_ptr<StackSamplingProfiler>> profilers;
897 sampling_completed[i] = 1321 CreateProfilers(target_thread_id, params, nullptr, &profiles, &profilers,
898 MakeUnique<WaitableEvent>(WaitableEvent::ResetPolicy::AUTOMATIC, 1322 &sampling_completed);
899 WaitableEvent::InitialState::NOT_SIGNALED); 1323
900 const StackSamplingProfiler::CompletedCallback callback = 1324 profilers[0]->Start();
901 Bind(&SaveProfilesAndSignalEvent, Unretained(&profiles[i]), 1325 profilers[1]->Start();
902 Unretained(sampling_completed[i].get())); 1326
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. 1327 // Wait for one profiler to finish.
917 size_t completed_profiler = 1328 size_t completed_profiler = WaitForSamplingComplete(&sampling_completed);
918 WaitableEvent::WaitMany(sampling_completed_rawptrs.data(), 2); 1329 ASSERT_EQ(1u, profiles[completed_profiler].size());
1330
1331 size_t other_profiler = 1 - completed_profiler;
1332 // Wait for the other profiler to finish.
1333 sampling_completed[other_profiler]->Wait();
1334 ASSERT_EQ(1u, profiles[other_profiler].size());
1335
1336 // Ensure each got the correct number of samples.
1337 EXPECT_EQ(9u, profiles[0][0].samples.size());
1338 EXPECT_EQ(8u, profiles[1][0].samples.size());
1339 });
1340 }
1341
1342 // Checks that several mixed sampling requests execute in parallel.
1343 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED)
1344 #define MAYBE_ConcurrentProfiling_Mixed ConcurrentProfiling_Mixed
1345 #else
1346 #define MAYBE_ConcurrentProfiling_Mixed DISABLED_ConcurrentProfiling_Mixed
1347 #endif
1348 TEST(StackSamplingProfilerTest, MAYBE_ConcurrentProfiling_Mixed) {
1349 StackSamplingProfiler::TestAPI::Reset();
1350 StackSamplingProfiler::TestAPI::DisableIdleShutdown();
1351
1352 WithTargetThread([](PlatformThreadId target_thread_id) {
1353 std::vector<SamplingParams> params(3);
1354
1355 params[0].initial_delay = TimeDelta::FromMilliseconds(8);
1356 params[0].sampling_interval = TimeDelta::FromMilliseconds(4);
1357 params[0].samples_per_burst = 10;
1358
1359 params[1].initial_delay = TimeDelta::FromMilliseconds(9);
1360 params[1].sampling_interval = TimeDelta::FromMilliseconds(3);
1361 params[1].samples_per_burst = 10;
1362
1363 params[2].initial_delay = TimeDelta::FromMilliseconds(10);
1364 params[2].sampling_interval = TimeDelta::FromMilliseconds(2);
1365 params[2].samples_per_burst = 10;
1366
1367 std::vector<CallStackProfiles> profiles;
1368 std::vector<std::unique_ptr<WaitableEvent>> sampling_completed;
1369 std::vector<std::unique_ptr<StackSamplingProfiler>> profilers;
1370 CreateProfilers(target_thread_id, params, nullptr, &profiles, &profilers,
1371 &sampling_completed);
1372
1373 for (size_t i = 0; i < profilers.size(); ++i)
1374 profilers[i]->Start();
1375
1376 // Wait for one profiler to finish.
1377 size_t completed_profiler = WaitForSamplingComplete(&sampling_completed);
919 EXPECT_EQ(1u, profiles[completed_profiler].size()); 1378 EXPECT_EQ(1u, profiles[completed_profiler].size());
920 1379 // Stop and destroy all profilers, always in the same order. Don't crash.
921 size_t other_profiler = 1 - completed_profiler; 1380 for (size_t i = 0; i < profilers.size(); ++i)
922 // Give the other profiler a chance to run and observe that it hasn't. 1381 profilers[i]->Stop();
923 EXPECT_FALSE(sampling_completed[other_profiler]->TimedWait( 1382 for (size_t i = 0; i < profilers.size(); ++i)
924 TimeDelta::FromMilliseconds(25))); 1383 profilers[i].reset();
925 1384 });
926 // Start the other profiler again and it should run. 1385 }
927 profiler[other_profiler]->Start(); 1386
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 1387 // Checks that a stack that runs through another library produces a stack with
934 // the expected functions. 1388 // the expected functions.
935 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED) 1389 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED)
936 #define MAYBE_OtherLibrary OtherLibrary 1390 #define MAYBE_OtherLibrary OtherLibrary
937 #else 1391 #else
938 #define MAYBE_OtherLibrary DISABLED_OtherLibrary 1392 #define MAYBE_OtherLibrary DISABLED_OtherLibrary
939 #endif 1393 #endif
940 TEST(StackSamplingProfilerTest, MAYBE_OtherLibrary) { 1394 TEST(StackSamplingProfilerTest, MAYBE_OtherLibrary) {
1395 StackSamplingProfiler::TestAPI::Reset();
1396
941 SamplingParams params; 1397 SamplingParams params;
942 params.sampling_interval = TimeDelta::FromMilliseconds(0); 1398 params.sampling_interval = TimeDelta::FromMilliseconds(0);
943 params.samples_per_burst = 1; 1399 params.samples_per_burst = 1;
944 1400
945 std::vector<CallStackProfile> profiles; 1401 std::vector<CallStackProfile> profiles;
946 { 1402 {
947 ScopedNativeLibrary other_library(LoadOtherLibrary()); 1403 ScopedNativeLibrary other_library(LoadOtherLibrary());
948 WithTargetThread( 1404 WithTargetThread(
949 [&params, &profiles](PlatformThreadId target_thread_id) { 1405 [&params, &profiles](PlatformThreadId target_thread_id) {
950 WaitableEvent sampling_thread_completed( 1406 WaitableEvent sampling_thread_completed(
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
1002 } 1458 }
1003 1459
1004 // Checks that a stack that runs through a library that is unloading produces a 1460 // Checks that a stack that runs through a library that is unloading produces a
1005 // stack, and doesn't crash. 1461 // stack, and doesn't crash.
1006 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED) 1462 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED)
1007 #define MAYBE_UnloadingLibrary UnloadingLibrary 1463 #define MAYBE_UnloadingLibrary UnloadingLibrary
1008 #else 1464 #else
1009 #define MAYBE_UnloadingLibrary DISABLED_UnloadingLibrary 1465 #define MAYBE_UnloadingLibrary DISABLED_UnloadingLibrary
1010 #endif 1466 #endif
1011 TEST(StackSamplingProfilerTest, MAYBE_UnloadingLibrary) { 1467 TEST(StackSamplingProfilerTest, MAYBE_UnloadingLibrary) {
1468 StackSamplingProfiler::TestAPI::Reset();
1012 TestLibraryUnload(false); 1469 TestLibraryUnload(false);
1013 } 1470 }
1014 1471
1015 // Checks that a stack that runs through a library that has been unloaded 1472 // Checks that a stack that runs through a library that has been unloaded
1016 // produces a stack, and doesn't crash. 1473 // produces a stack, and doesn't crash.
1017 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED) 1474 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED)
1018 #define MAYBE_UnloadedLibrary UnloadedLibrary 1475 #define MAYBE_UnloadedLibrary UnloadedLibrary
1019 #else 1476 #else
1020 #define MAYBE_UnloadedLibrary DISABLED_UnloadedLibrary 1477 #define MAYBE_UnloadedLibrary DISABLED_UnloadedLibrary
1021 #endif 1478 #endif
1022 TEST(StackSamplingProfilerTest, MAYBE_UnloadedLibrary) { 1479 TEST(StackSamplingProfilerTest, MAYBE_UnloadedLibrary) {
1480 StackSamplingProfiler::TestAPI::Reset();
1023 TestLibraryUnload(true); 1481 TestLibraryUnload(true);
1024 } 1482 }
1025 1483
1484 // Checks that different threads can be sampled in parallel.
1485 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED)
1486 #define MAYBE_MultipleSampledThreads MultipleSampledThreads
1487 #else
1488 #define MAYBE_MultipleSampledThreads DISABLED_MultipleSampledThreads
1489 #endif
1490 TEST(StackSamplingProfilerTest, MAYBE_MultipleSampledThreads) {
1491 StackSamplingProfiler::TestAPI::Reset();
1492
1493 // Create target threads. The extra parethesis around the StackConfiguration
1494 // call are to avoid the most-vexing-parse problem.
1495 TargetThread target_thread1((StackConfiguration(StackConfiguration::NORMAL)));
1496 TargetThread target_thread2((StackConfiguration(StackConfiguration::NORMAL)));
1497 PlatformThreadHandle target_thread_handle1, target_thread_handle2;
1498 EXPECT_TRUE(
1499 PlatformThread::Create(0, &target_thread1, &target_thread_handle1));
1500 EXPECT_TRUE(
1501 PlatformThread::Create(0, &target_thread2, &target_thread_handle2));
1502 target_thread1.WaitForThreadStart();
1503 target_thread2.WaitForThreadStart();
1504
1505 // Providing an initial delay makes it more likely that both will be
1506 // scheduled before either starts to run. Once started, samples will
1507 // run ordered by their scheduled, interleaved times regardless of
1508 // whatever interval the thread wakes up.
1509 SamplingParams params1, params2;
1510 params1.initial_delay = TimeDelta::FromMilliseconds(10);
1511 params1.sampling_interval = TimeDelta::FromMilliseconds(1);
1512 params1.samples_per_burst = 9;
1513 params2.initial_delay = TimeDelta::FromMilliseconds(10);
1514 params2.sampling_interval = TimeDelta::FromMilliseconds(1);
1515 params2.samples_per_burst = 8;
1516
1517 std::vector<CallStackProfile> profiles1, profiles2;
1518
1519 WaitableEvent sampling_thread_completed1(
1520 WaitableEvent::ResetPolicy::MANUAL,
1521 WaitableEvent::InitialState::NOT_SIGNALED);
1522 const StackSamplingProfiler::CompletedCallback callback1 =
1523 Bind(&SaveProfilesAndSignalEvent, Unretained(&profiles1),
1524 Unretained(&sampling_thread_completed1));
1525 StackSamplingProfiler profiler1(target_thread1.id(), params1, callback1);
1526
1527 WaitableEvent sampling_thread_completed2(
1528 WaitableEvent::ResetPolicy::MANUAL,
1529 WaitableEvent::InitialState::NOT_SIGNALED);
1530 const StackSamplingProfiler::CompletedCallback callback2 =
1531 Bind(&SaveProfilesAndSignalEvent, Unretained(&profiles2),
1532 Unretained(&sampling_thread_completed2));
1533 StackSamplingProfiler profiler2(target_thread2.id(), params2, callback2);
1534
1535 // Finally the real work.
1536 profiler1.Start();
1537 profiler2.Start();
1538 sampling_thread_completed1.Wait();
1539 sampling_thread_completed2.Wait();
1540 ASSERT_EQ(1u, profiles1.size());
1541 EXPECT_EQ(9u, profiles1[0].samples.size());
1542 ASSERT_EQ(1u, profiles2.size());
1543 EXPECT_EQ(8u, profiles2[0].samples.size());
1544
1545 target_thread1.SignalThreadToFinish();
1546 target_thread2.SignalThreadToFinish();
1547 PlatformThread::Join(target_thread_handle1);
1548 PlatformThread::Join(target_thread_handle2);
1549 }
1550
1551 // A simple thread that runs a profiler on another thread.
1552 class ProfilerThread : public SimpleThread {
1553 public:
1554 ProfilerThread(const std::string& name,
1555 PlatformThreadId thread_id,
1556 const SamplingParams& params)
1557 : SimpleThread(name, Options()),
1558 run_(WaitableEvent::ResetPolicy::MANUAL,
1559 WaitableEvent::InitialState::NOT_SIGNALED),
1560 completed_(WaitableEvent::ResetPolicy::MANUAL,
1561 WaitableEvent::InitialState::NOT_SIGNALED),
1562 profiler_(thread_id,
1563 params,
1564 Bind(&SaveProfilesAndSignalEvent,
1565 Unretained(&profiles_),
1566 Unretained(&completed_))) {}
1567
1568 void Run() override {
1569 run_.Wait();
1570 profiler_.Start();
1571 }
1572
1573 void Go() { run_.Signal(); }
1574
1575 void Wait() { completed_.Wait(); }
1576
1577 CallStackProfiles& profiles() { return profiles_; }
1578
1579 private:
1580 WaitableEvent run_;
1581
1582 CallStackProfiles profiles_;
1583 WaitableEvent completed_;
1584 StackSamplingProfiler profiler_;
1585 };
1586
1587 // Checks that different threads can run samplers in parallel.
1588 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED)
1589 #define MAYBE_MultipleProfilerThreads MultipleProfilerThreads
1590 #else
1591 #define MAYBE_MultipleProfilerThreads DISABLED_MultipleProfilerThreads
1592 #endif
1593 TEST(StackSamplingProfilerTest, MAYBE_MultipleProfilerThreads) {
1594 StackSamplingProfiler::TestAPI::Reset();
1595
1596 WithTargetThread([](PlatformThreadId target_thread_id) {
1597 // Providing an initial delay makes it more likely that both will be
1598 // scheduled before either starts to run. Once started, samples will
1599 // run ordered by their scheduled, interleaved times regardless of
1600 // whatever interval the thread wakes up.
1601 SamplingParams params1, params2;
1602 params1.initial_delay = TimeDelta::FromMilliseconds(10);
1603 params1.sampling_interval = TimeDelta::FromMilliseconds(1);
1604 params1.samples_per_burst = 9;
1605 params2.initial_delay = TimeDelta::FromMilliseconds(10);
1606 params2.sampling_interval = TimeDelta::FromMilliseconds(1);
1607 params2.samples_per_burst = 8;
1608
1609 // Start the profiler threads and give them a moment to get going.
1610 ProfilerThread profiler1("profiler1", target_thread_id, params1);
1611 ProfilerThread profiler2("profiler2", target_thread_id, params2);
Mike Wittman 2017/03/30 16:18:38 How about profiler_thread1 and profiler_thread2 to
bcwhite 2017/03/30 18:54:51 Done.
Mike Wittman 2017/03/31 01:38:22 I don't see this change in the patch sets.
bcwhite 2017/03/31 13:57:56 It's there; #38 and above.
Mike Wittman 2017/03/31 18:12:32 Ah, the thread names changed. My comment was inten
1612 profiler1.Start();
1613 profiler2.Start();
1614 PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(10));
1615
1616 // This will (approximately) synchronize the two threads.
1617 profiler1.Go();
1618 profiler2.Go();
1619
1620 // Wait for them both to finish and validate collection.
1621 profiler1.Wait();
1622 profiler2.Wait();
1623 ASSERT_EQ(1u, profiler1.profiles().size());
1624 EXPECT_EQ(9u, profiler1.profiles()[0].samples.size());
1625 ASSERT_EQ(1u, profiler2.profiles().size());
1626 EXPECT_EQ(8u, profiler2.profiles()[0].samples.size());
1627
1628 profiler1.Join();
1629 profiler2.Join();
1630 });
1631 }
1632
1026 } // namespace base 1633 } // 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