stack_sampling_profiler.h 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  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
  3. // found in the LICENSE file.
  4. #ifndef BASE_PROFILER_STACK_SAMPLING_PROFILER_H_
  5. #define BASE_PROFILER_STACK_SAMPLING_PROFILER_H_
  6. #include <memory>
  7. #include <vector>
  8. #include "base/base_export.h"
  9. #include "base/macros.h"
  10. #include "base/optional.h"
  11. #include "base/profiler/profile_builder.h"
  12. #include "base/profiler/sampling_profiler_thread_token.h"
  13. #include "base/profiler/unwinder.h"
  14. #include "base/synchronization/waitable_event.h"
  15. #include "base/threading/platform_thread.h"
  16. #include "base/time/time.h"
  17. namespace base {
  18. class Unwinder;
  19. class StackSampler;
  20. class StackSamplerTestDelegate;
  21. // StackSamplingProfiler periodically stops a thread to sample its stack, for
  22. // the purpose of collecting information about which code paths are
  23. // executing. This information is used in aggregate by UMA to identify hot
  24. // and/or janky code paths.
  25. //
  26. // Sample StackSamplingProfiler usage:
  27. //
  28. // // Create and customize params as desired.
  29. // base::StackStackSamplingProfiler::SamplingParams params;
  30. //
  31. // // To process the profiles, use a custom ProfileBuilder subclass:
  32. // class SubProfileBuilder : public base::ProfileBuilder {...}
  33. //
  34. // // Then create the profiler:
  35. // base::StackSamplingProfiler profiler(base::PlatformThread::CurrentId(),
  36. // params, std::make_unique<SubProfileBuilder>(...));
  37. //
  38. // // On Android the |sampler| is not implemented in base. So, client can pass
  39. // // in |sampler| to use while profiling.
  40. // base::StackSamplingProfiler profiler(base::PlatformThread::CurrentId(),
  41. // params, std::make_unique<SubProfileBuilder>(...), <optional> sampler);
  42. //
  43. // // Then start the profiling.
  44. // profiler.Start();
  45. // // ... work being done on the target thread here ...
  46. // // Optionally stop collection before complete per params.
  47. // profiler.Stop();
  48. //
  49. // The default SamplingParams causes stacks to be recorded in a single profile
  50. // at a 10Hz interval for a total of 30 seconds. All of these parameters may be
  51. // altered as desired.
  52. //
  53. // When a call stack profile is complete, or the profiler is stopped,
  54. // ProfileBuilder's OnProfileCompleted function is called from a thread created
  55. // by the profiler.
  56. class BASE_EXPORT StackSamplingProfiler {
  57. public:
  58. // Represents parameters that configure the sampling.
  59. struct BASE_EXPORT SamplingParams {
  60. // Time to delay before first samples are taken.
  61. TimeDelta initial_delay = TimeDelta::FromMilliseconds(0);
  62. // Number of samples to record per profile.
  63. int samples_per_profile = 300;
  64. // Interval between samples during a sampling profile. This is the desired
  65. // duration from the start of one sample to the start of the next sample.
  66. TimeDelta sampling_interval = TimeDelta::FromMilliseconds(100);
  67. };
  68. // Creates a profiler for the specified thread. |unwinders| is required on
  69. // Android since the unwinder is provided outside StackSamplingProfiler, but
  70. // must be empty on other platforms. When attempting to unwind, the relative
  71. // priority of unwinders is the inverse of the order in |unwinders|. An
  72. // optional |test_delegate| can be supplied by tests.
  73. //
  74. // The caller must ensure that this object gets destroyed before the thread
  75. // exits.
  76. StackSamplingProfiler(
  77. SamplingProfilerThreadToken thread_token,
  78. const SamplingParams& params,
  79. std::unique_ptr<ProfileBuilder> profile_builder,
  80. std::vector<std::unique_ptr<Unwinder>> core_unwinders = {},
  81. StackSamplerTestDelegate* test_delegate = nullptr);
  82. // Same as above function, with custom |sampler| implementation. The sampler
  83. // on Android is not implemented in base.
  84. StackSamplingProfiler(const SamplingParams& params,
  85. std::unique_ptr<ProfileBuilder> profile_builder,
  86. std::unique_ptr<StackSampler> sampler);
  87. // Stops any profiling currently taking place before destroying the profiler.
  88. // This will block until profile_builder_'s OnProfileCompleted function has
  89. // executed if profiling has started but not already finished.
  90. ~StackSamplingProfiler();
  91. // Initializes the profiler and starts sampling. Might block on a
  92. // WaitableEvent if this StackSamplingProfiler was previously started and
  93. // recently stopped, while the previous profiling phase winds down.
  94. void Start();
  95. // Stops the profiler and any ongoing sampling. This method will return
  96. // immediately with the profile_builder_'s OnProfileCompleted function being
  97. // run asynchronously. At most one more stack sample will be taken after this
  98. // method returns. Calling this function is optional; if not invoked profiling
  99. // terminates when all the profiling samples specified in the SamplingParams
  100. // are completed or the profiler object is destroyed, whichever occurs first.
  101. void Stop();
  102. // Adds an auxiliary unwinder to handle additional, non-native-code unwind
  103. // scenarios.
  104. void AddAuxUnwinder(std::unique_ptr<Unwinder> unwinder);
  105. // Test peer class. These functions are purely for internal testing of
  106. // StackSamplingProfiler; DO NOT USE within tests outside of this directory.
  107. // The functions are static because they interact with the sampling thread, a
  108. // singleton used by all StackSamplingProfiler objects. The functions can
  109. // only be called by the same thread that started the sampling.
  110. class BASE_EXPORT TestPeer {
  111. public:
  112. // Resets the internal state to that of a fresh start. This is necessary
  113. // so that tests don't inherit state from previous tests.
  114. static void Reset();
  115. // Returns whether the sampling thread is currently running or not.
  116. static bool IsSamplingThreadRunning();
  117. // Disables inherent idle-shutdown behavior.
  118. static void DisableIdleShutdown();
  119. // Initiates an idle shutdown task, as though the idle timer had expired,
  120. // causing the thread to exit. There is no "idle" check so this must be
  121. // called only when all sampling tasks have completed. This blocks until
  122. // the task has been executed, though the actual stopping of the thread
  123. // still happens asynchronously. Watch IsSamplingThreadRunning() to know
  124. // when the thread has exited. If |simulate_intervening_start| is true then
  125. // this method will make it appear to the shutdown task that a new profiler
  126. // was started between when the idle-shutdown was initiated and when it
  127. // runs.
  128. static void PerformSamplingThreadIdleShutdown(
  129. bool simulate_intervening_start);
  130. // Provides access to the method computing the next sample time.
  131. static TimeTicks GetNextSampleTime(TimeTicks scheduled_current_sample_time,
  132. TimeDelta sampling_interval,
  133. TimeTicks now);
  134. };
  135. private:
  136. // SamplingThread is a separate thread used to suspend and sample stacks from
  137. // the target thread.
  138. class SamplingThread;
  139. // Friend the global function from sample_metadata.cc so that it can call into
  140. // the function below.
  141. friend void ApplyMetadataToPastSamplesImpl(TimeTicks period_start,
  142. TimeTicks period_end,
  143. int64_t name_hash,
  144. Optional<int64_t> key,
  145. int64_t value);
  146. // Apply metadata to already recorded samples. See the
  147. // ApplyMetadataToPastSamples() docs in sample_metadata.h.
  148. static void ApplyMetadataToPastSamples(TimeTicks period_start,
  149. TimeTicks period_end,
  150. int64_t name_hash,
  151. Optional<int64_t> key,
  152. int64_t value);
  153. // The thread whose stack will be sampled.
  154. SamplingProfilerThreadToken thread_token_;
  155. const SamplingParams params_;
  156. // Receives the sampling data and builds a profile. The ownership of this
  157. // object will be transferred to the sampling thread when thread sampling
  158. // starts.
  159. std::unique_ptr<ProfileBuilder> profile_builder_;
  160. // Stack sampler which stops the thread and collects stack frames. The
  161. // ownership of this object will be transferred to the sampling thread when
  162. // thread sampling starts.
  163. std::unique_ptr<StackSampler> sampler_;
  164. // This starts "signaled", is reset when sampling begins, and is signaled
  165. // when that sampling is complete and the profile_builder_'s
  166. // OnProfileCompleted function has executed.
  167. WaitableEvent profiling_inactive_;
  168. // An ID uniquely identifying this profiler to the sampling thread. This
  169. // will be an internal "null" value when no collection has been started.
  170. int profiler_id_;
  171. DISALLOW_COPY_AND_ASSIGN(StackSamplingProfiler);
  172. };
  173. } // namespace base
  174. #endif // BASE_PROFILER_STACK_SAMPLING_PROFILER_H_