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