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

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

Powered by Google App Engine
This is Rietveld 408576698