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> |
(...skipping 375 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
386 | 386 |
387 // Captures profiles as specified by |params| on the TargetThread, and returns | 387 // Captures profiles as specified by |params| on the TargetThread, and returns |
388 // them in |profiles|. Waits up to |profiler_wait_time| for the profiler to | 388 // them in |profiles|. Waits up to |profiler_wait_time| for the profiler to |
389 // complete. | 389 // complete. |
390 void CaptureProfiles(const SamplingParams& params, TimeDelta profiler_wait_time, | 390 void CaptureProfiles(const SamplingParams& params, TimeDelta profiler_wait_time, |
391 CallStackProfiles* profiles) { | 391 CallStackProfiles* profiles) { |
392 profiles->clear(); | 392 profiles->clear(); |
393 | 393 |
394 WithTargetThread([¶ms, profiles, | 394 WithTargetThread([¶ms, profiles, |
395 profiler_wait_time](PlatformThreadId target_thread_id) { | 395 profiler_wait_time](PlatformThreadId target_thread_id) { |
| 396 WaitableEvent profiler_completed(WaitableEvent::ResetPolicy::MANUAL, |
| 397 WaitableEvent::InitialState::NOT_SIGNALED); |
396 WaitableEvent sampling_thread_completed( | 398 WaitableEvent sampling_thread_completed( |
397 WaitableEvent::ResetPolicy::MANUAL, | 399 WaitableEvent::ResetPolicy::MANUAL, |
398 WaitableEvent::InitialState::NOT_SIGNALED); | 400 WaitableEvent::InitialState::NOT_SIGNALED); |
399 const StackSamplingProfiler::CompletedCallback callback = | 401 const StackSamplingProfiler::CompletedCallback callback = |
400 Bind(&SaveProfilesAndSignalEvent, Unretained(profiles), | 402 Bind(&SaveProfilesAndSignalEvent, Unretained(profiles), |
401 Unretained(&sampling_thread_completed)); | 403 Unretained(&sampling_thread_completed)); |
402 StackSamplingProfiler profiler(target_thread_id, params, callback); | 404 StackSamplingProfiler profiler(target_thread_id, params, callback); |
403 profiler.Start(); | 405 profiler.Start(); |
404 sampling_thread_completed.TimedWait(profiler_wait_time); | 406 sampling_thread_completed.TimedWait(profiler_wait_time); |
405 profiler.Stop(); | 407 profiler.Stop(&profiler_completed); |
406 sampling_thread_completed.Wait(); | 408 profiler_completed.Wait(); |
| 409 ASSERT_TRUE(sampling_thread_completed.IsSignaled()); |
407 }); | 410 }); |
408 } | 411 } |
409 | 412 |
410 // If this executable was linked with /INCREMENTAL (the default for non-official | 413 // If this executable was linked with /INCREMENTAL (the default for non-official |
411 // debug and release builds on Windows), function addresses do not correspond to | 414 // debug and release builds on Windows), function addresses do not correspond to |
412 // function code itself, but instead to instructions in the Incremental Link | 415 // function code itself, but instead to instructions in the Incremental Link |
413 // Table that jump to the functions. Checks for a jump instruction and if | 416 // Table that jump to the functions. Checks for a jump instruction and if |
414 // present does a little decompilation to find the function's actual starting | 417 // present does a little decompilation to find the function's actual starting |
415 // address. | 418 // address. |
416 const void* MaybeFixupFunctionAddressForILT(const void* function_address) { | 419 const void* MaybeFixupFunctionAddressForILT(const void* function_address) { |
(...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
758 reinterpret_cast<const void*>(&TargetThread::CallWithAlloca)) | 761 reinterpret_cast<const void*>(&TargetThread::CallWithAlloca)) |
759 << " was not found in stack:\n" | 762 << " was not found in stack:\n" |
760 << FormatSampleForDiagnosticOutput(sample, profile.modules); | 763 << FormatSampleForDiagnosticOutput(sample, profile.modules); |
761 | 764 |
762 // These frames should be adjacent on the stack. | 765 // These frames should be adjacent on the stack. |
763 EXPECT_EQ(1, alloca_frame - end_frame) | 766 EXPECT_EQ(1, alloca_frame - end_frame) |
764 << "Stack:\n" | 767 << "Stack:\n" |
765 << FormatSampleForDiagnosticOutput(sample, profile.modules); | 768 << FormatSampleForDiagnosticOutput(sample, profile.modules); |
766 } | 769 } |
767 | 770 |
768 // Checks that the fire-and-forget interface works. | |
769 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED) | |
770 #define MAYBE_StartAndRunAsync StartAndRunAsync | |
771 #else | |
772 #define MAYBE_StartAndRunAsync DISABLED_StartAndRunAsync | |
773 #endif | |
774 TEST(StackSamplingProfilerTest, MAYBE_StartAndRunAsync) { | |
775 // StartAndRunAsync requires the caller to have a message loop. | |
776 MessageLoop message_loop; | |
777 | |
778 SamplingParams params; | |
779 params.samples_per_burst = 1; | |
780 | |
781 CallStackProfiles profiles; | |
782 WithTargetThread([¶ms, &profiles](PlatformThreadId target_thread_id) { | |
783 WaitableEvent sampling_thread_completed( | |
784 WaitableEvent::ResetPolicy::AUTOMATIC, | |
785 WaitableEvent::InitialState::NOT_SIGNALED); | |
786 const StackSamplingProfiler::CompletedCallback callback = | |
787 Bind(&SaveProfilesAndSignalEvent, Unretained(&profiles), | |
788 Unretained(&sampling_thread_completed)); | |
789 StackSamplingProfiler::StartAndRunAsync(target_thread_id, params, callback); | |
790 RunLoop().RunUntilIdle(); | |
791 sampling_thread_completed.Wait(); | |
792 }); | |
793 | |
794 ASSERT_EQ(1u, profiles.size()); | |
795 } | |
796 | |
797 // Checks that the expected number of profiles and samples are present in the | 771 // Checks that the expected number of profiles and samples are present in the |
798 // call stack profiles produced. | 772 // call stack profiles produced. |
799 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED) | 773 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED) |
800 #define MAYBE_MultipleProfilesAndSamples MultipleProfilesAndSamples | 774 #define MAYBE_MultipleProfilesAndSamples MultipleProfilesAndSamples |
801 #else | 775 #else |
802 #define MAYBE_MultipleProfilesAndSamples DISABLED_MultipleProfilesAndSamples | 776 #define MAYBE_MultipleProfilesAndSamples DISABLED_MultipleProfilesAndSamples |
803 #endif | 777 #endif |
804 TEST(StackSamplingProfilerTest, MAYBE_MultipleProfilesAndSamples) { | 778 TEST(StackSamplingProfilerTest, MAYBE_MultipleProfilesAndSamples) { |
805 SamplingParams params; | 779 SamplingParams params; |
806 params.burst_interval = params.sampling_interval = | 780 params.burst_interval = params.sampling_interval = |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
891 target_thread_id, params, Bind(&SaveProfiles, Unretained(&profiles)))); | 865 target_thread_id, params, Bind(&SaveProfiles, Unretained(&profiles)))); |
892 profiler->Start(); | 866 profiler->Start(); |
893 profiler.reset(); | 867 profiler.reset(); |
894 | 868 |
895 // Wait longer than a sample interval to catch any use-after-free actions by | 869 // Wait longer than a sample interval to catch any use-after-free actions by |
896 // the profiler thread. | 870 // the profiler thread. |
897 PlatformThread::Sleep(TimeDelta::FromMilliseconds(50)); | 871 PlatformThread::Sleep(TimeDelta::FromMilliseconds(50)); |
898 }); | 872 }); |
899 } | 873 } |
900 | 874 |
| 875 #if 0 // Not currently supported. |
901 // Checks that we can destroy the thread under test while profiling. | 876 // Checks that we can destroy the thread under test while profiling. |
902 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED) | 877 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED) |
903 #define MAYBE_DestroyThreadWhileProfiling DestroyThreadWhileProfiling | 878 #define MAYBE_DestroyThreadWhileProfiling DestroyThreadWhileProfiling |
904 #else | 879 #else |
905 #define MAYBE_DestroyThreadWhileProfiling DISABLED_DestroyThreadWhileProfiling | 880 #define MAYBE_DestroyThreadWhileProfiling DISABLED_DestroyThreadWhileProfiling |
906 #endif | 881 #endif |
907 TEST(StackSamplingProfilerTest, MAYBE_DestroyThreadWhileProfiling) { | 882 TEST(StackSamplingProfilerTest, MAYBE_DestroyThreadWhileProfiling) { |
908 // Set up a thread for testing. | 883 // Set up a thread for testing. |
909 StackConfiguration stack_config(StackConfiguration::NORMAL); | 884 StackConfiguration stack_config(StackConfiguration::NORMAL); |
910 TargetThread target_thread(stack_config); | 885 TargetThread target_thread(stack_config); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
944 | 919 |
945 // Stop the target thread. | 920 // Stop the target thread. |
946 target_thread.SignalThreadToFinish(); | 921 target_thread.SignalThreadToFinish(); |
947 PlatformThread::Join(target_thread_handle); | 922 PlatformThread::Join(target_thread_handle); |
948 | 923 |
949 // Wait for one more sampling attempt. | 924 // Wait for one more sampling attempt. |
950 thread_sampled.Reset(); | 925 thread_sampled.Reset(); |
951 thread_sampled.Wait(); | 926 thread_sampled.Wait(); |
952 | 927 |
953 // Stop sampling and wait for it to finish. | 928 // Stop sampling and wait for it to finish. |
954 profiler.Stop(); | 929 profiler.Stop(nullptr); |
955 sampling_thread_completed.Wait(); | 930 sampling_thread_completed.Wait(); |
956 | 931 |
957 // There should be one profile in which the first sample has frames and | 932 // There should be one profile in which the first sample has frames and |
958 // the last does not. | 933 // the last does not. |
959 ASSERT_EQ(1U, profiles.size()); | 934 ASSERT_EQ(1U, profiles.size()); |
960 EXPECT_NE(0U, profiles[0].samples.front().frames.size()); | 935 EXPECT_NE(0U, profiles[0].samples.front().frames.size()); |
961 EXPECT_EQ(0U, profiles[0].samples.back().frames.size()); | 936 EXPECT_EQ(0U, profiles[0].samples.back().frames.size()); |
962 } | 937 } |
| 938 #endif |
963 | 939 |
964 // Checks that the same profiler may be run multiple times. | 940 // Checks that the same profiler may be run multiple times. |
965 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED) | 941 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED) |
966 #define MAYBE_CanRunMultipleTimes CanRunMultipleTimes | 942 #define MAYBE_CanRunMultipleTimes CanRunMultipleTimes |
967 #else | 943 #else |
968 #define MAYBE_CanRunMultipleTimes DISABLED_CanRunMultipleTimes | 944 #define MAYBE_CanRunMultipleTimes DISABLED_CanRunMultipleTimes |
969 #endif | 945 #endif |
970 TEST(StackSamplingProfilerTest, MAYBE_CanRunMultipleTimes) { | 946 TEST(StackSamplingProfilerTest, MAYBE_CanRunMultipleTimes) { |
971 StackSamplingProfiler::SetSamplingThreadIdleShutdownTimeForTesting(0); | 947 StackSamplingProfiler::SetSamplingThreadIdleShutdownTimeForTesting(0); |
972 | 948 |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1138 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED) | 1114 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED) |
1139 #define MAYBE_UnloadedLibrary UnloadedLibrary | 1115 #define MAYBE_UnloadedLibrary UnloadedLibrary |
1140 #else | 1116 #else |
1141 #define MAYBE_UnloadedLibrary DISABLED_UnloadedLibrary | 1117 #define MAYBE_UnloadedLibrary DISABLED_UnloadedLibrary |
1142 #endif | 1118 #endif |
1143 TEST(StackSamplingProfilerTest, MAYBE_UnloadedLibrary) { | 1119 TEST(StackSamplingProfilerTest, MAYBE_UnloadedLibrary) { |
1144 TestLibraryUnload(true); | 1120 TestLibraryUnload(true); |
1145 } | 1121 } |
1146 | 1122 |
1147 } // namespace base | 1123 } // namespace base |
OLD | NEW |