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

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

Powered by Google App Engine
This is Rietveld 408576698