| 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 |