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 #ifndef BASE_TRACE_EVENT_MEMORY_DUMP_MANAGER_H_ | 5 #ifndef BASE_TRACE_EVENT_MEMORY_DUMP_MANAGER_H_ |
6 #define BASE_TRACE_EVENT_MEMORY_DUMP_MANAGER_H_ | 6 #define BASE_TRACE_EVENT_MEMORY_DUMP_MANAGER_H_ |
7 | 7 |
8 #include <stdint.h> | 8 #include <stdint.h> |
9 | 9 |
10 #include <map> | 10 #include <map> |
11 #include <memory> | 11 #include <memory> |
12 #include <unordered_set> | 12 #include <unordered_set> |
13 #include <vector> | 13 #include <vector> |
14 | 14 |
15 #include "base/atomicops.h" | 15 #include "base/atomicops.h" |
16 #include "base/containers/hash_tables.h" | 16 #include "base/containers/hash_tables.h" |
17 #include "base/macros.h" | 17 #include "base/macros.h" |
18 #include "base/memory/ref_counted.h" | 18 #include "base/memory/ref_counted.h" |
19 #include "base/memory/singleton.h" | 19 #include "base/memory/singleton.h" |
20 #include "base/synchronization/lock.h" | 20 #include "base/synchronization/lock.h" |
21 #include "base/trace_event/memory_allocator_dump.h" | 21 #include "base/trace_event/memory_allocator_dump.h" |
22 #include "base/trace_event/memory_dump_provider_info.h" | 22 #include "base/trace_event/memory_dump_provider_info.h" |
23 #include "base/trace_event/memory_dump_request_args.h" | 23 #include "base/trace_event/memory_dump_request_args.h" |
24 #include "base/trace_event/process_memory_dump.h" | 24 #include "base/trace_event/process_memory_dump.h" |
25 #include "base/trace_event/trace_event.h" | 25 #include "base/trace_event/trace_event.h" |
26 | 26 |
27 // Forward declare |MemoryDumpManagerDelegateImplTest| so that we can make it a | 27 // Forward declare |ProcessLocalDumpManagerImplTest| so that we can make it a |
28 // friend of |MemoryDumpManager| and give it access to |SetInstanceForTesting|. | 28 // friend of |MemoryDumpManager| and give it access to |SetInstanceForTesting|. |
29 namespace memory_instrumentation { | 29 namespace memory_instrumentation { |
30 | 30 |
31 class MemoryDumpManagerDelegateImplTest; | 31 class ProcessLocalDumpManagerImplTest; |
32 | 32 |
33 } // namespace memory_instrumentation | 33 } // namespace memory_instrumentation |
34 | 34 |
35 namespace base { | 35 namespace base { |
36 | 36 |
37 class SingleThreadTaskRunner; | 37 class SingleThreadTaskRunner; |
38 class Thread; | 38 class Thread; |
39 | 39 |
40 namespace trace_event { | 40 namespace trace_event { |
41 | 41 |
42 class MemoryTracingObserver; | 42 class MemoryTracingObserver; |
43 class MemoryDumpManagerDelegate; | |
44 class MemoryDumpProvider; | 43 class MemoryDumpProvider; |
45 class MemoryDumpSessionState; | 44 class MemoryDumpSessionState; |
46 | 45 |
47 // This is the interface exposed to the rest of the codebase to deal with | 46 // This is the interface exposed to the rest of the codebase to deal with |
48 // memory tracing. The main entry point for clients is represented by | 47 // memory tracing. The main entry point for clients is represented by |
49 // RequestDumpPoint(). The extension by Un(RegisterDumpProvider). | 48 // RequestDumpPoint(). The extension by Un(RegisterDumpProvider). |
50 class BASE_EXPORT MemoryDumpManager { | 49 class BASE_EXPORT MemoryDumpManager { |
51 public: | 50 public: |
| 51 using RequestGlobalDumpFunction = |
| 52 RepeatingCallback<void(const MemoryDumpRequestArgs& args, |
| 53 const GlobalMemoryDumpCallback& callback)>; |
| 54 |
52 static const char* const kTraceCategory; | 55 static const char* const kTraceCategory; |
53 static const char* const kLogPrefix; | 56 static const char* const kLogPrefix; |
54 | 57 |
55 // This value is returned as the tracing id of the child processes by | 58 // This value is returned as the tracing id of the child processes by |
56 // GetTracingProcessId() when tracing is not enabled. | 59 // GetTracingProcessId() when tracing is not enabled. |
57 static const uint64_t kInvalidTracingProcessId; | 60 static const uint64_t kInvalidTracingProcessId; |
58 | 61 |
59 static MemoryDumpManager* GetInstance(); | 62 static MemoryDumpManager* GetInstance(); |
60 | 63 |
61 // Invoked once per process to listen to trace begin / end events. | 64 // Invoked once per process to listen to trace begin / end events. |
62 // Initialization can happen after (Un)RegisterMemoryDumpProvider() calls | 65 // Initialization can happen after (Un)RegisterMemoryDumpProvider() calls |
63 // and the MemoryDumpManager guarantees to support this. | 66 // and the MemoryDumpManager guarantees to support this. |
64 // On the other side, the MemoryDumpManager will not be fully operational | 67 // On the other side, the MemoryDumpManager will not be fully operational |
65 // (i.e. will NACK any RequestGlobalMemoryDump()) until initialized. | 68 // (i.e. will NACK any RequestGlobalMemoryDump()) until initialized. |
66 // Arguments: | 69 // Arguments: |
67 // delegate: inversion-of-control interface for embedder-specific behaviors | 70 // request_dump_function: Function to invoke a global dump. Global dump |
68 // (multiprocess handshaking). See the lifetime and thread-safety | 71 // involves embedder-specific behaviors like multiprocess handshaking. |
69 // requirements in the |MemoryDumpManagerDelegate| docstring. | 72 // is_coordinator: True when current process coodinates the periodic dump |
70 void Initialize(std::unique_ptr<MemoryDumpManagerDelegate> delegate); | 73 // triggering. |
| 74 void Initialize(RequestGlobalDumpFunction request_dump_function, |
| 75 bool is_coordinator); |
71 | 76 |
72 // (Un)Registers a MemoryDumpProvider instance. | 77 // (Un)Registers a MemoryDumpProvider instance. |
73 // Args: | 78 // Args: |
74 // - mdp: the MemoryDumpProvider instance to be registered. MemoryDumpManager | 79 // - mdp: the MemoryDumpProvider instance to be registered. MemoryDumpManager |
75 // does NOT take memory ownership of |mdp|, which is expected to either | 80 // does NOT take memory ownership of |mdp|, which is expected to either |
76 // be a singleton or unregister itself. | 81 // be a singleton or unregister itself. |
77 // - name: a friendly name (duplicates allowed). Used for debugging and | 82 // - name: a friendly name (duplicates allowed). Used for debugging and |
78 // run-time profiling of memory-infra internals. Must be a long-lived | 83 // run-time profiling of memory-infra internals. Must be a long-lived |
79 // C string. | 84 // C string. |
80 // - task_runner: either a SingleThreadTaskRunner or SequencedTaskRunner. All | 85 // - task_runner: either a SingleThreadTaskRunner or SequencedTaskRunner. All |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
123 // Prepare MemoryDumpManager for RequestGlobalMemoryDump calls. | 128 // Prepare MemoryDumpManager for RequestGlobalMemoryDump calls. |
124 // Starts the MemoryDumpManager thread. | 129 // Starts the MemoryDumpManager thread. |
125 // Also uses the given config to initialize the peak detector, | 130 // Also uses the given config to initialize the peak detector, |
126 // scheduler and heap profiler. | 131 // scheduler and heap profiler. |
127 void Enable(const TraceConfig::MemoryDumpConfig&); | 132 void Enable(const TraceConfig::MemoryDumpConfig&); |
128 | 133 |
129 // Tearsdown the MemoryDumpManager thread and various other state set up by | 134 // Tearsdown the MemoryDumpManager thread and various other state set up by |
130 // Enable. | 135 // Enable. |
131 void Disable(); | 136 void Disable(); |
132 | 137 |
| 138 // NOTE: Use RequestGlobalDump() to create memory dumps. Creates a memory dump |
| 139 // for the current process and appends it to the trace. |callback| will be |
| 140 // invoked asynchronously upon completion on the same thread on which |
| 141 // CreateProcessDump() was called. This method should only be used by the |
| 142 // embedder while creating a global memory dump. |
| 143 void CreateProcessDump(const MemoryDumpRequestArgs& args, |
| 144 const ProcessMemoryDumpCallback& callback); |
| 145 |
133 // Enable heap profiling if kEnableHeapProfiling is specified. | 146 // Enable heap profiling if kEnableHeapProfiling is specified. |
134 void EnableHeapProfilingIfNeeded(); | 147 void EnableHeapProfilingIfNeeded(); |
135 | 148 |
136 // Returns true if the dump mode is allowed for current tracing session. | 149 // Returns true if the dump mode is allowed for current tracing session. |
137 bool IsDumpModeAllowed(MemoryDumpLevelOfDetail dump_mode); | 150 bool IsDumpModeAllowed(MemoryDumpLevelOfDetail dump_mode); |
138 | 151 |
139 // Lets tests see if a dump provider is registered. | 152 // Lets tests see if a dump provider is registered. |
140 bool IsDumpProviderRegisteredForTesting(MemoryDumpProvider*); | 153 bool IsDumpProviderRegisteredForTesting(MemoryDumpProvider*); |
141 | 154 |
142 // Returns the MemoryDumpSessionState object, which is shared by all the | 155 // Returns the MemoryDumpSessionState object, which is shared by all the |
(...skipping 22 matching lines...) Expand all Loading... |
165 }; | 178 }; |
166 | 179 |
167 // When set to true, calling |RegisterMemoryDumpProvider| is a no-op. | 180 // When set to true, calling |RegisterMemoryDumpProvider| is a no-op. |
168 void set_dumper_registrations_ignored_for_testing(bool ignored) { | 181 void set_dumper_registrations_ignored_for_testing(bool ignored) { |
169 dumper_registrations_ignored_for_testing_ = ignored; | 182 dumper_registrations_ignored_for_testing_ = ignored; |
170 } | 183 } |
171 | 184 |
172 private: | 185 private: |
173 friend std::default_delete<MemoryDumpManager>; // For the testing instance. | 186 friend std::default_delete<MemoryDumpManager>; // For the testing instance. |
174 friend struct DefaultSingletonTraits<MemoryDumpManager>; | 187 friend struct DefaultSingletonTraits<MemoryDumpManager>; |
175 friend class MemoryDumpManagerDelegate; | |
176 friend class MemoryDumpManagerTest; | 188 friend class MemoryDumpManagerTest; |
177 friend class memory_instrumentation::MemoryDumpManagerDelegateImplTest; | 189 friend class memory_instrumentation::ProcessLocalDumpManagerImplTest; |
178 | 190 |
179 // Holds the state of a process memory dump that needs to be carried over | 191 // Holds the state of a process memory dump that needs to be carried over |
180 // across task runners in order to fulfil an asynchronous CreateProcessDump() | 192 // across task runners in order to fulfil an asynchronous CreateProcessDump() |
181 // request. At any time exactly one task runner owns a | 193 // request. At any time exactly one task runner owns a |
182 // ProcessMemoryDumpAsyncState. | 194 // ProcessMemoryDumpAsyncState. |
183 struct ProcessMemoryDumpAsyncState { | 195 struct ProcessMemoryDumpAsyncState { |
184 ProcessMemoryDumpAsyncState( | 196 ProcessMemoryDumpAsyncState( |
185 MemoryDumpRequestArgs req_args, | 197 MemoryDumpRequestArgs req_args, |
186 const MemoryDumpProviderInfo::OrderedSet& dump_providers, | 198 const MemoryDumpProviderInfo::OrderedSet& dump_providers, |
187 scoped_refptr<MemoryDumpSessionState> session_state, | 199 scoped_refptr<MemoryDumpSessionState> session_state, |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
238 | 250 |
239 MemoryDumpManager(); | 251 MemoryDumpManager(); |
240 virtual ~MemoryDumpManager(); | 252 virtual ~MemoryDumpManager(); |
241 | 253 |
242 static void SetInstanceForTesting(MemoryDumpManager* instance); | 254 static void SetInstanceForTesting(MemoryDumpManager* instance); |
243 static uint32_t GetDumpsSumKb(const std::string&, const ProcessMemoryDump*); | 255 static uint32_t GetDumpsSumKb(const std::string&, const ProcessMemoryDump*); |
244 | 256 |
245 void FinalizeDumpAndAddToTrace( | 257 void FinalizeDumpAndAddToTrace( |
246 std::unique_ptr<ProcessMemoryDumpAsyncState> pmd_async_state); | 258 std::unique_ptr<ProcessMemoryDumpAsyncState> pmd_async_state); |
247 | 259 |
248 // Internal, used only by MemoryDumpManagerDelegate. | |
249 // Creates a memory dump for the current process and appends it to the trace. | |
250 // |callback| will be invoked asynchronously upon completion on the same | |
251 // thread on which CreateProcessDump() was called. | |
252 void CreateProcessDump(const MemoryDumpRequestArgs& args, | |
253 const ProcessMemoryDumpCallback& callback); | |
254 | |
255 // Calls InvokeOnMemoryDump() for the next MDP on the task runner specified by | 260 // Calls InvokeOnMemoryDump() for the next MDP on the task runner specified by |
256 // the MDP while registration. On failure to do so, skips and continues to | 261 // the MDP while registration. On failure to do so, skips and continues to |
257 // next MDP. | 262 // next MDP. |
258 void SetupNextMemoryDump( | 263 void SetupNextMemoryDump( |
259 std::unique_ptr<ProcessMemoryDumpAsyncState> pmd_async_state); | 264 std::unique_ptr<ProcessMemoryDumpAsyncState> pmd_async_state); |
260 | 265 |
261 // Invokes OnMemoryDump() of the next MDP and calls SetupNextMemoryDump() at | 266 // Invokes OnMemoryDump() of the next MDP and calls SetupNextMemoryDump() at |
262 // the end to continue the ProcessMemoryDump. Should be called on the MDP task | 267 // the end to continue the ProcessMemoryDump. Should be called on the MDP task |
263 // runner. | 268 // runner. |
264 void InvokeOnMemoryDump(ProcessMemoryDumpAsyncState* owned_pmd_async_state); | 269 void InvokeOnMemoryDump(ProcessMemoryDumpAsyncState* owned_pmd_async_state); |
(...skipping 19 matching lines...) Expand all Loading... |
284 MemoryDumpProviderInfo::OrderedSet dump_providers_; | 289 MemoryDumpProviderInfo::OrderedSet dump_providers_; |
285 | 290 |
286 // Shared among all the PMDs to keep state scoped to the tracing session. | 291 // Shared among all the PMDs to keep state scoped to the tracing session. |
287 scoped_refptr<MemoryDumpSessionState> session_state_; | 292 scoped_refptr<MemoryDumpSessionState> session_state_; |
288 | 293 |
289 // The list of names of dump providers that are blacklisted from strict thread | 294 // The list of names of dump providers that are blacklisted from strict thread |
290 // affinity check on unregistration. | 295 // affinity check on unregistration. |
291 std::unordered_set<StringPiece, StringPieceHash> | 296 std::unordered_set<StringPiece, StringPieceHash> |
292 strict_thread_check_blacklist_; | 297 strict_thread_check_blacklist_; |
293 | 298 |
294 std::unique_ptr<MemoryDumpManagerDelegate> delegate_; | |
295 std::unique_ptr<MemoryTracingObserver> tracing_observer_; | 299 std::unique_ptr<MemoryTracingObserver> tracing_observer_; |
296 | 300 |
297 // Protects from concurrent accesses to the |dump_providers_*| and |delegate_| | 301 // Function provided by the embedder to handle global dump requests. |
298 // to guard against disabling logging while dumping on another thread. | 302 RequestGlobalDumpFunction request_dump_function_; |
| 303 |
| 304 // True when current process coordinates the periodic dump triggering. |
| 305 bool is_coordinator_; |
| 306 |
| 307 // Protects from concurrent accesses to the local state, eg: to guard against |
| 308 // disabling logging while dumping on another thread. |
299 Lock lock_; | 309 Lock lock_; |
300 | 310 |
301 // Optimization to avoid attempting any memory dump (i.e. to not walk an empty | 311 // Optimization to avoid attempting any memory dump (i.e. to not walk an empty |
302 // dump_providers_enabled_ list) when tracing is not enabled. | 312 // dump_providers_enabled_ list) when tracing is not enabled. |
303 subtle::AtomicWord memory_tracing_enabled_; | 313 subtle::AtomicWord memory_tracing_enabled_; |
304 | 314 |
305 // Thread used for MemoryDumpProviders which don't specify a task runner | 315 // Thread used for MemoryDumpProviders which don't specify a task runner |
306 // affinity. | 316 // affinity. |
307 std::unique_ptr<Thread> dump_thread_; | 317 std::unique_ptr<Thread> dump_thread_; |
308 | 318 |
309 // The unique id of the child process. This is created only for tracing and is | 319 // The unique id of the child process. This is created only for tracing and is |
310 // expected to be valid only when tracing is enabled. | 320 // expected to be valid only when tracing is enabled. |
311 uint64_t tracing_process_id_; | 321 uint64_t tracing_process_id_; |
312 | 322 |
313 // When true, calling |RegisterMemoryDumpProvider| is a no-op. | 323 // When true, calling |RegisterMemoryDumpProvider| is a no-op. |
314 bool dumper_registrations_ignored_for_testing_; | 324 bool dumper_registrations_ignored_for_testing_; |
315 | 325 |
316 // Whether new memory dump providers should be told to enable heap profiling. | 326 // Whether new memory dump providers should be told to enable heap profiling. |
317 bool heap_profiling_enabled_; | 327 bool heap_profiling_enabled_; |
318 | 328 |
319 DISALLOW_COPY_AND_ASSIGN(MemoryDumpManager); | 329 DISALLOW_COPY_AND_ASSIGN(MemoryDumpManager); |
320 }; | 330 }; |
321 | 331 |
322 // The delegate is supposed to be long lived (read: a Singleton) and thread | |
323 // safe (i.e. should expect calls from any thread and handle thread hopping). | |
324 class BASE_EXPORT MemoryDumpManagerDelegate { | |
325 public: | |
326 MemoryDumpManagerDelegate() {} | |
327 virtual ~MemoryDumpManagerDelegate() {} | |
328 | |
329 virtual void RequestGlobalMemoryDump( | |
330 const MemoryDumpRequestArgs& args, | |
331 const GlobalMemoryDumpCallback& callback) = 0; | |
332 | |
333 virtual bool IsCoordinator() const = 0; | |
334 | |
335 protected: | |
336 void CreateProcessDump(const MemoryDumpRequestArgs& args, | |
337 const ProcessMemoryDumpCallback& callback) { | |
338 MemoryDumpManager::GetInstance()->CreateProcessDump(args, callback); | |
339 } | |
340 | |
341 private: | |
342 DISALLOW_COPY_AND_ASSIGN(MemoryDumpManagerDelegate); | |
343 }; | |
344 | |
345 } // namespace trace_event | 332 } // namespace trace_event |
346 } // namespace base | 333 } // namespace base |
347 | 334 |
348 #endif // BASE_TRACE_EVENT_MEMORY_DUMP_MANAGER_H_ | 335 #endif // BASE_TRACE_EVENT_MEMORY_DUMP_MANAGER_H_ |
OLD | NEW |