stack_sampling_profiler.h 9.8 KB

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