memory_dump_manager.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  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_TRACE_EVENT_MEMORY_DUMP_MANAGER_H_
  5. #define BASE_TRACE_EVENT_MEMORY_DUMP_MANAGER_H_
  6. #include <stdint.h>
  7. #include <map>
  8. #include <memory>
  9. #include <unordered_set>
  10. #include <vector>
  11. #include "base/base_export.h"
  12. #include "base/gtest_prod_util.h"
  13. #include "base/memory/singleton.h"
  14. #include "base/synchronization/lock.h"
  15. #include "base/trace_event/memory_allocator_dump.h"
  16. #include "base/trace_event/memory_dump_provider_info.h"
  17. #include "base/trace_event/memory_dump_request_args.h"
  18. #include "base/trace_event/process_memory_dump.h"
  19. #include "base/trace_event/trace_event.h"
  20. namespace base {
  21. class SequencedTaskRunner;
  22. class SingleThreadTaskRunner;
  23. class Thread;
  24. namespace trace_event {
  25. class MemoryDumpProvider;
  26. // This is the interface exposed to the rest of the codebase to deal with
  27. // memory tracing. The main entry point for clients is represented by
  28. // RequestDumpPoint(). The extension by Un(RegisterDumpProvider).
  29. class BASE_EXPORT MemoryDumpManager {
  30. public:
  31. using RequestGlobalDumpFunction =
  32. RepeatingCallback<void(MemoryDumpType, MemoryDumpLevelOfDetail)>;
  33. static constexpr const char* const kTraceCategory =
  34. TRACE_DISABLED_BY_DEFAULT("memory-infra");
  35. // This value is returned as the tracing id of the child processes by
  36. // GetTracingProcessId() when tracing is not enabled.
  37. static const uint64_t kInvalidTracingProcessId;
  38. static MemoryDumpManager* GetInstance();
  39. static std::unique_ptr<MemoryDumpManager> CreateInstanceForTesting();
  40. MemoryDumpManager(const MemoryDumpManager&) = delete;
  41. MemoryDumpManager& operator=(const MemoryDumpManager&) = delete;
  42. // Invoked once per process to listen to trace begin / end events.
  43. // Initialization can happen after (Un)RegisterMemoryDumpProvider() calls
  44. // and the MemoryDumpManager guarantees to support this.
  45. // On the other side, the MemoryDumpManager will not be fully operational
  46. // (any CreateProcessDump() will return a failure) until initialized.
  47. // Arguments:
  48. // is_coordinator: True when current process coordinates the periodic dump
  49. // triggering.
  50. // request_dump_function: Function to invoke a global dump. Global dump
  51. // involves embedder-specific behaviors like multiprocess handshaking.
  52. // TODO(primiano): this is only required to trigger global dumps from
  53. // the scheduler. Should be removed once they are both moved out of base.
  54. void Initialize(RequestGlobalDumpFunction request_dump_function,
  55. bool is_coordinator);
  56. // (Un)Registers a MemoryDumpProvider instance.
  57. // Args:
  58. // - mdp: the MemoryDumpProvider instance to be registered. MemoryDumpManager
  59. // does NOT take memory ownership of |mdp|, which is expected to either
  60. // be a singleton or unregister itself.
  61. // - name: a friendly name (duplicates allowed). Used for debugging and
  62. // run-time profiling of memory-infra internals. Must be a long-lived
  63. // C string.
  64. // - task_runner: either a SingleThreadTaskRunner or SequencedTaskRunner. All
  65. // the calls to |mdp| will be run on the given |task_runner|. If passed
  66. // null |mdp| should be able to handle calls on arbitrary threads.
  67. // - options: extra optional arguments. See memory_dump_provider.h.
  68. void RegisterDumpProvider(MemoryDumpProvider* mdp,
  69. const char* name,
  70. scoped_refptr<SingleThreadTaskRunner> task_runner);
  71. void RegisterDumpProvider(MemoryDumpProvider* mdp,
  72. const char* name,
  73. scoped_refptr<SingleThreadTaskRunner> task_runner,
  74. MemoryDumpProvider::Options options);
  75. void RegisterDumpProviderWithSequencedTaskRunner(
  76. MemoryDumpProvider* mdp,
  77. const char* name,
  78. scoped_refptr<SequencedTaskRunner> task_runner,
  79. MemoryDumpProvider::Options options);
  80. void UnregisterDumpProvider(MemoryDumpProvider* mdp);
  81. // Unregisters an unbound dump provider and takes care about its deletion
  82. // asynchronously. Can be used only for for dump providers with no
  83. // task-runner affinity.
  84. // This method takes ownership of the dump provider and guarantees that:
  85. // - The |mdp| will be deleted at some point in the near future.
  86. // - Its deletion will not happen concurrently with the OnMemoryDump() call.
  87. // Note that OnMemoryDump() calls can still happen after this method returns.
  88. void UnregisterAndDeleteDumpProviderSoon(
  89. std::unique_ptr<MemoryDumpProvider> mdp);
  90. // Prepare MemoryDumpManager for CreateProcessDump() calls for tracing-related
  91. // modes (i.e. |level_of_detail| != SUMMARY_ONLY).
  92. // Also initializes the scheduler with the given config.
  93. void SetupForTracing(const TraceConfig::MemoryDumpConfig&);
  94. // Tear-down tracing related state.
  95. // Non-tracing modes (e.g. SUMMARY_ONLY) will continue to work.
  96. void TeardownForTracing();
  97. // Creates a memory dump for the current process and appends it to the trace.
  98. // |callback| will be invoked asynchronously upon completion on the same
  99. // thread on which CreateProcessDump() was called. This method should only be
  100. // used by the memory-infra service while creating a global memory dump.
  101. void CreateProcessDump(const MemoryDumpRequestArgs& args,
  102. ProcessMemoryDumpCallback callback);
  103. // Lets tests see if a dump provider is registered.
  104. bool IsDumpProviderRegisteredForTesting(MemoryDumpProvider*);
  105. // Returns a unique id for identifying the processes. The id can be
  106. // retrieved by child processes only when tracing is enabled. This is
  107. // intended to express cross-process sharing of memory dumps on the
  108. // child-process side, without having to know its own child process id.
  109. uint64_t GetTracingProcessId() const { return tracing_process_id_; }
  110. void set_tracing_process_id(uint64_t tracing_process_id) {
  111. tracing_process_id_ = tracing_process_id;
  112. }
  113. // Returns the name for a the allocated_objects dump. Use this to declare
  114. // suballocator dumps from other dump providers.
  115. // It will return nullptr if there is no dump provider for the system
  116. // allocator registered (which is currently the case for Mac OS).
  117. const char* system_allocator_pool_name() const {
  118. return kSystemAllocatorPoolName;
  119. }
  120. // When set to true, calling |RegisterMemoryDumpProvider| is a no-op.
  121. void set_dumper_registrations_ignored_for_testing(bool ignored) {
  122. dumper_registrations_ignored_for_testing_ = ignored;
  123. }
  124. scoped_refptr<SequencedTaskRunner> GetDumpThreadTaskRunner();
  125. private:
  126. friend std::default_delete<MemoryDumpManager>; // For the testing instance.
  127. friend struct DefaultSingletonTraits<MemoryDumpManager>;
  128. friend class MemoryDumpManagerTest;
  129. FRIEND_TEST_ALL_PREFIXES(MemoryDumpManagerTest,
  130. NoStackOverflowWithTooManyMDPs);
  131. // Holds the state of a process memory dump that needs to be carried over
  132. // across task runners in order to fulfill an asynchronous CreateProcessDump()
  133. // request. At any time exactly one task runner owns a
  134. // ProcessMemoryDumpAsyncState.
  135. struct ProcessMemoryDumpAsyncState {
  136. ProcessMemoryDumpAsyncState(
  137. MemoryDumpRequestArgs req_args,
  138. const MemoryDumpProviderInfo::OrderedSet& dump_providers,
  139. ProcessMemoryDumpCallback callback,
  140. scoped_refptr<SequencedTaskRunner> dump_thread_task_runner);
  141. ProcessMemoryDumpAsyncState(const ProcessMemoryDumpAsyncState&) = delete;
  142. ProcessMemoryDumpAsyncState& operator=(const ProcessMemoryDumpAsyncState&) =
  143. delete;
  144. ~ProcessMemoryDumpAsyncState();
  145. // A ProcessMemoryDump to collect data from MemoryDumpProviders.
  146. std::unique_ptr<ProcessMemoryDump> process_memory_dump;
  147. // The arguments passed to the initial CreateProcessDump() request.
  148. const MemoryDumpRequestArgs req_args;
  149. // An ordered sequence of dump providers that have to be invoked to complete
  150. // the dump. This is a copy of |dump_providers_| at the beginning of a dump
  151. // and becomes empty at the end, when all dump providers have been invoked.
  152. std::vector<scoped_refptr<MemoryDumpProviderInfo>> pending_dump_providers;
  153. // Callback passed to the initial call to CreateProcessDump().
  154. ProcessMemoryDumpCallback callback;
  155. // The thread on which FinishAsyncProcessDump() (and hence |callback|)
  156. // should be invoked. This is the thread on which the initial
  157. // CreateProcessDump() request was called.
  158. const scoped_refptr<SingleThreadTaskRunner> callback_task_runner;
  159. // The thread on which unbound dump providers should be invoked.
  160. // This is essentially |dump_thread_|.task_runner() but needs to be kept
  161. // as a separate variable as it needs to be accessed by arbitrary dumpers'
  162. // threads outside of the lock_ to avoid races when disabling tracing.
  163. // It is immutable for all the duration of a tracing session.
  164. const scoped_refptr<SequencedTaskRunner> dump_thread_task_runner;
  165. };
  166. static const int kMaxConsecutiveFailuresCount;
  167. static const char* const kSystemAllocatorPoolName;
  168. MemoryDumpManager();
  169. virtual ~MemoryDumpManager();
  170. static void SetInstanceForTesting(MemoryDumpManager* instance);
  171. // Lazily initializes dump_thread_ and returns its TaskRunner.
  172. scoped_refptr<base::SequencedTaskRunner> GetOrCreateBgTaskRunnerLocked()
  173. EXCLUSIVE_LOCKS_REQUIRED(lock_);
  174. // Calls InvokeOnMemoryDump() for the each MDP that belongs to the current
  175. // task runner and switches to the task runner of the next MDP. Handles
  176. // failures in MDP and thread hops, and always calls FinishAsyncProcessDump()
  177. // at the end.
  178. void ContinueAsyncProcessDump(
  179. ProcessMemoryDumpAsyncState* owned_pmd_async_state);
  180. // Invokes OnMemoryDump() of the given MDP. Should be called on the MDP task
  181. // runner.
  182. void InvokeOnMemoryDump(MemoryDumpProviderInfo* mdpinfo,
  183. ProcessMemoryDump* pmd);
  184. void FinishAsyncProcessDump(
  185. std::unique_ptr<ProcessMemoryDumpAsyncState> pmd_async_state);
  186. // Helper for RegierDumpProvider* functions.
  187. void RegisterDumpProviderInternal(
  188. MemoryDumpProvider* mdp,
  189. const char* name,
  190. scoped_refptr<SequencedTaskRunner> task_runner,
  191. const MemoryDumpProvider::Options& options);
  192. // Helper for the public UnregisterDumpProvider* functions.
  193. void UnregisterDumpProviderInternal(MemoryDumpProvider* mdp,
  194. bool take_mdp_ownership_and_delete_async);
  195. bool can_request_global_dumps() const {
  196. return !request_dump_function_.is_null();
  197. }
  198. // An ordered set of registered MemoryDumpProviderInfo(s), sorted by task
  199. // runner affinity (MDPs belonging to the same task runners are adjacent).
  200. MemoryDumpProviderInfo::OrderedSet dump_providers_ GUARDED_BY(lock_);
  201. // Function provided by the embedder to handle global dump requests.
  202. RequestGlobalDumpFunction request_dump_function_;
  203. // True when current process coordinates the periodic dump triggering.
  204. bool is_coordinator_ GUARDED_BY(lock_) = false;
  205. // Protects from concurrent accesses to the local state, eg: to guard against
  206. // disabling logging while dumping on another thread.
  207. Lock lock_;
  208. // Thread used for MemoryDumpProviders which don't specify a task runner
  209. // affinity.
  210. std::unique_ptr<Thread> dump_thread_ GUARDED_BY(lock_);
  211. // The unique id of the child process. This is created only for tracing and is
  212. // expected to be valid only when tracing is enabled.
  213. uint64_t tracing_process_id_ = kInvalidTracingProcessId;
  214. // When true, calling |RegisterMemoryDumpProvider| is a no-op.
  215. bool dumper_registrations_ignored_for_testing_ = false;
  216. };
  217. } // namespace trace_event
  218. } // namespace base
  219. #endif // BASE_TRACE_EVENT_MEMORY_DUMP_MANAGER_H_