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 MemoryDumpManagerDelegate; | |
43 class MemoryDumpProvider; | 42 class MemoryDumpProvider; |
44 class MemoryDumpSessionState; | 43 class MemoryDumpSessionState; |
45 | 44 |
46 // This is the interface exposed to the rest of the codebase to deal with | 45 // This is the interface exposed to the rest of the codebase to deal with |
47 // memory tracing. The main entry point for clients is represented by | 46 // memory tracing. The main entry point for clients is represented by |
48 // RequestDumpPoint(). The extension by Un(RegisterDumpProvider). | 47 // RequestDumpPoint(). The extension by Un(RegisterDumpProvider). |
49 class BASE_EXPORT MemoryDumpManager : public TraceLog::EnabledStateObserver { | 48 class BASE_EXPORT MemoryDumpManager : public TraceLog::EnabledStateObserver { |
50 public: | 49 public: |
51 static const char* const kTraceCategory; | 50 static const char* const kTraceCategory; |
52 static const char* const kLogPrefix; | 51 static const char* const kLogPrefix; |
53 | 52 |
54 // This value is returned as the tracing id of the child processes by | 53 // This value is returned as the tracing id of the child processes by |
55 // GetTracingProcessId() when tracing is not enabled. | 54 // GetTracingProcessId() when tracing is not enabled. |
56 static const uint64_t kInvalidTracingProcessId; | 55 static const uint64_t kInvalidTracingProcessId; |
57 | 56 |
58 static MemoryDumpManager* GetInstance(); | 57 static MemoryDumpManager* GetInstance(); |
59 | 58 |
60 // Invoked once per process to listen to trace begin / end events. | 59 // Invoked once per process to listen to trace begin / end events. |
61 // Initialization can happen after (Un)RegisterMemoryDumpProvider() calls | 60 // Initialization can happen after (Un)RegisterMemoryDumpProvider() calls |
62 // and the MemoryDumpManager guarantees to support this. | 61 // and the MemoryDumpManager guarantees to support this. |
63 // On the other side, the MemoryDumpManager will not be fully operational | 62 // On the other side, the MemoryDumpManager will not be fully operational |
64 // (i.e. will NACK any RequestGlobalMemoryDump()) until initialized. | 63 // (i.e. will NACK any RequestGlobalMemoryDump()) until initialized. |
65 // Arguments: | 64 // Arguments: |
66 // delegate: inversion-of-control interface for embedder-specific behaviors | 65 // request_dump_callback: Callback to invoke a global dump. Global dump |
67 // (multiprocess handshaking). See the lifetime and thread-safety | 66 // involves embedder-specific behaviors like multiprocess handshaking. |
68 // requirements in the |MemoryDumpManagerDelegate| docstring. | 67 // is_coordinator: True when current process coodinates the periodic dump |
69 void Initialize(std::unique_ptr<MemoryDumpManagerDelegate> delegate); | 68 // triggering. |
69 using RequestGlobalDumpCallback = | |
Primiano Tucci (use gerrit)
2017/04/19 15:44:34
small nit: type declarations should go up, after p
ssid
2017/04/20 01:18:21
I don't think this should be moved. Let's say in f
Primiano Tucci (use gerrit)
2017/04/20 20:30:05
Hmm good point. ACK
| |
70 RepeatingCallback<void(const MemoryDumpRequestArgs& args, | |
71 const GlobalMemoryDumpCallback& callback)>; | |
72 void Initialize(RequestGlobalDumpCallback request_dump_callback, | |
73 bool is_coordinator); | |
70 | 74 |
71 // (Un)Registers a MemoryDumpProvider instance. | 75 // (Un)Registers a MemoryDumpProvider instance. |
72 // Args: | 76 // Args: |
73 // - mdp: the MemoryDumpProvider instance to be registered. MemoryDumpManager | 77 // - mdp: the MemoryDumpProvider instance to be registered. MemoryDumpManager |
74 // does NOT take memory ownership of |mdp|, which is expected to either | 78 // does NOT take memory ownership of |mdp|, which is expected to either |
75 // be a singleton or unregister itself. | 79 // be a singleton or unregister itself. |
76 // - name: a friendly name (duplicates allowed). Used for debugging and | 80 // - name: a friendly name (duplicates allowed). Used for debugging and |
77 // run-time profiling of memory-infra internals. Must be a long-lived | 81 // run-time profiling of memory-infra internals. Must be a long-lived |
78 // C string. | 82 // C string. |
79 // - task_runner: either a SingleThreadTaskRunner or SequencedTaskRunner. All | 83 // - task_runner: either a SingleThreadTaskRunner or SequencedTaskRunner. All |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
112 // processes have dumped) and its success (true iff all the dumps were | 116 // processes have dumped) and its success (true iff all the dumps were |
113 // successful). | 117 // successful). |
114 void RequestGlobalDump(MemoryDumpType dump_type, | 118 void RequestGlobalDump(MemoryDumpType dump_type, |
115 MemoryDumpLevelOfDetail level_of_detail, | 119 MemoryDumpLevelOfDetail level_of_detail, |
116 const GlobalMemoryDumpCallback& callback); | 120 const GlobalMemoryDumpCallback& callback); |
117 | 121 |
118 // Same as above (still asynchronous), but without callback. | 122 // Same as above (still asynchronous), but without callback. |
119 void RequestGlobalDump(MemoryDumpType dump_type, | 123 void RequestGlobalDump(MemoryDumpType dump_type, |
120 MemoryDumpLevelOfDetail level_of_detail); | 124 MemoryDumpLevelOfDetail level_of_detail); |
121 | 125 |
126 // NOTE: Use RequestGlobalDump() to create memory dumps. Creates a memory dump | |
Primiano Tucci (use gerrit)
2017/04/19 15:44:34
Since you have the "This method should only be use
ssid
2017/04/20 01:18:21
I'd like to keep this note because it is really ea
Primiano Tucci (use gerrit)
2017/04/20 20:30:05
Acknowledged.
| |
127 // for the current process and appends it to the trace. |callback| will be | |
128 // invoked asynchronously upon completion on the same thread on which | |
129 // CreateProcessDump() was called. This method should only be used by the | |
130 // embedder while creating a global memory dump. | |
131 void CreateProcessDump(const MemoryDumpRequestArgs& args, | |
132 const ProcessMemoryDumpCallback& callback); | |
133 | |
122 // TraceLog::EnabledStateObserver implementation. | 134 // TraceLog::EnabledStateObserver implementation. |
123 void OnTraceLogEnabled() override; | 135 void OnTraceLogEnabled() override; |
124 void OnTraceLogDisabled() override; | 136 void OnTraceLogDisabled() override; |
125 | 137 |
126 // Enable heap profiling if kEnableHeapProfiling is specified. | 138 // Enable heap profiling if kEnableHeapProfiling is specified. |
127 void EnableHeapProfilingIfNeeded(); | 139 void EnableHeapProfilingIfNeeded(); |
128 | 140 |
129 // Returns true if the dump mode is allowed for current tracing session. | 141 // Returns true if the dump mode is allowed for current tracing session. |
130 bool IsDumpModeAllowed(MemoryDumpLevelOfDetail dump_mode); | 142 bool IsDumpModeAllowed(MemoryDumpLevelOfDetail dump_mode); |
131 | 143 |
(...skipping 26 matching lines...) Expand all Loading... | |
158 }; | 170 }; |
159 | 171 |
160 // When set to true, calling |RegisterMemoryDumpProvider| is a no-op. | 172 // When set to true, calling |RegisterMemoryDumpProvider| is a no-op. |
161 void set_dumper_registrations_ignored_for_testing(bool ignored) { | 173 void set_dumper_registrations_ignored_for_testing(bool ignored) { |
162 dumper_registrations_ignored_for_testing_ = ignored; | 174 dumper_registrations_ignored_for_testing_ = ignored; |
163 } | 175 } |
164 | 176 |
165 private: | 177 private: |
166 friend std::default_delete<MemoryDumpManager>; // For the testing instance. | 178 friend std::default_delete<MemoryDumpManager>; // For the testing instance. |
167 friend struct DefaultSingletonTraits<MemoryDumpManager>; | 179 friend struct DefaultSingletonTraits<MemoryDumpManager>; |
180 // todo fix | |
fmeawad
2017/04/18 14:48:11
Don't forget this TODO
ssid
2017/04/20 01:18:21
Done.
| |
168 friend class MemoryDumpManagerDelegate; | 181 friend class MemoryDumpManagerDelegate; |
169 friend class MemoryDumpManagerTest; | 182 friend class MemoryDumpManagerTest; |
170 friend class memory_instrumentation::MemoryDumpManagerDelegateImplTest; | 183 friend class memory_instrumentation::ProcessLocalDumpManagerImplTest; |
171 | 184 |
172 // Holds the state of a process memory dump that needs to be carried over | 185 // Holds the state of a process memory dump that needs to be carried over |
173 // across task runners in order to fulfil an asynchronous CreateProcessDump() | 186 // across task runners in order to fulfil an asynchronous CreateProcessDump() |
174 // request. At any time exactly one task runner owns a | 187 // request. At any time exactly one task runner owns a |
175 // ProcessMemoryDumpAsyncState. | 188 // ProcessMemoryDumpAsyncState. |
176 struct ProcessMemoryDumpAsyncState { | 189 struct ProcessMemoryDumpAsyncState { |
177 ProcessMemoryDumpAsyncState( | 190 ProcessMemoryDumpAsyncState( |
178 MemoryDumpRequestArgs req_args, | 191 MemoryDumpRequestArgs req_args, |
179 const MemoryDumpProviderInfo::OrderedSet& dump_providers, | 192 const MemoryDumpProviderInfo::OrderedSet& dump_providers, |
180 scoped_refptr<MemoryDumpSessionState> session_state, | 193 scoped_refptr<MemoryDumpSessionState> session_state, |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
230 static const char* const kSystemAllocatorPoolName; | 243 static const char* const kSystemAllocatorPoolName; |
231 | 244 |
232 MemoryDumpManager(); | 245 MemoryDumpManager(); |
233 ~MemoryDumpManager() override; | 246 ~MemoryDumpManager() override; |
234 | 247 |
235 static void SetInstanceForTesting(MemoryDumpManager* instance); | 248 static void SetInstanceForTesting(MemoryDumpManager* instance); |
236 static uint32_t GetDumpsSumKb(const std::string&, const ProcessMemoryDump*); | 249 static uint32_t GetDumpsSumKb(const std::string&, const ProcessMemoryDump*); |
237 static void FinalizeDumpAndAddToTrace( | 250 static void FinalizeDumpAndAddToTrace( |
238 std::unique_ptr<ProcessMemoryDumpAsyncState> pmd_async_state); | 251 std::unique_ptr<ProcessMemoryDumpAsyncState> pmd_async_state); |
239 | 252 |
240 // Internal, used only by MemoryDumpManagerDelegate. | |
241 // Creates a memory dump for the current process and appends it to the trace. | |
242 // |callback| will be invoked asynchronously upon completion on the same | |
243 // thread on which CreateProcessDump() was called. | |
244 void CreateProcessDump(const MemoryDumpRequestArgs& args, | |
245 const ProcessMemoryDumpCallback& callback); | |
246 | |
247 // Calls InvokeOnMemoryDump() for the next MDP on the task runner specified by | 253 // Calls InvokeOnMemoryDump() for the next MDP on the task runner specified by |
248 // the MDP while registration. On failure to do so, skips and continues to | 254 // the MDP while registration. On failure to do so, skips and continues to |
249 // next MDP. | 255 // next MDP. |
250 void SetupNextMemoryDump( | 256 void SetupNextMemoryDump( |
251 std::unique_ptr<ProcessMemoryDumpAsyncState> pmd_async_state); | 257 std::unique_ptr<ProcessMemoryDumpAsyncState> pmd_async_state); |
252 | 258 |
253 // Invokes OnMemoryDump() of the next MDP and calls SetupNextMemoryDump() at | 259 // Invokes OnMemoryDump() of the next MDP and calls SetupNextMemoryDump() at |
254 // the end to continue the ProcessMemoryDump. Should be called on the MDP task | 260 // the end to continue the ProcessMemoryDump. Should be called on the MDP task |
255 // runner. | 261 // runner. |
256 void InvokeOnMemoryDump(ProcessMemoryDumpAsyncState* owned_pmd_async_state); | 262 void InvokeOnMemoryDump(ProcessMemoryDumpAsyncState* owned_pmd_async_state); |
(...skipping 19 matching lines...) Expand all Loading... | |
276 MemoryDumpProviderInfo::OrderedSet dump_providers_; | 282 MemoryDumpProviderInfo::OrderedSet dump_providers_; |
277 | 283 |
278 // Shared among all the PMDs to keep state scoped to the tracing session. | 284 // Shared among all the PMDs to keep state scoped to the tracing session. |
279 scoped_refptr<MemoryDumpSessionState> session_state_; | 285 scoped_refptr<MemoryDumpSessionState> session_state_; |
280 | 286 |
281 // The list of names of dump providers that are blacklisted from strict thread | 287 // The list of names of dump providers that are blacklisted from strict thread |
282 // affinity check on unregistration. | 288 // affinity check on unregistration. |
283 std::unordered_set<StringPiece, StringPieceHash> | 289 std::unordered_set<StringPiece, StringPieceHash> |
284 strict_thread_check_blacklist_; | 290 strict_thread_check_blacklist_; |
285 | 291 |
286 std::unique_ptr<MemoryDumpManagerDelegate> delegate_; | 292 // Callback provided by the embedder to handle global dump requests. |
293 RequestGlobalDumpCallback request_dump_callback_; | |
Primiano Tucci (use gerrit)
2017/04/19 15:44:34
s/callback/function/
ssid
2017/04/20 01:18:21
Done.
| |
287 | 294 |
288 // Protects from concurrent accesses to the |dump_providers_*| and |delegate_| | 295 // True when current process coordinates the periodic dump triggering. |
289 // to guard against disabling logging while dumping on another thread. | 296 bool is_coordinator_; |
297 | |
298 // Protects from concurrent accesses to the |dump_providers_*| and | |
299 // |is_coordinator_| to guard against disabling logging while dumping on | |
Primiano Tucci (use gerrit)
2017/04/19 15:44:34
I think over time more stuff got serialized aroudn
ssid
2017/04/20 01:18:20
Done.
| |
300 // another thread. | |
290 Lock lock_; | 301 Lock lock_; |
291 | 302 |
292 // Optimization to avoid attempting any memory dump (i.e. to not walk an empty | 303 // Optimization to avoid attempting any memory dump (i.e. to not walk an empty |
293 // dump_providers_enabled_ list) when tracing is not enabled. | 304 // dump_providers_enabled_ list) when tracing is not enabled. |
294 subtle::AtomicWord memory_tracing_enabled_; | 305 subtle::AtomicWord memory_tracing_enabled_; |
295 | 306 |
296 // Thread used for MemoryDumpProviders which don't specify a task runner | 307 // Thread used for MemoryDumpProviders which don't specify a task runner |
297 // affinity. | 308 // affinity. |
298 std::unique_ptr<Thread> dump_thread_; | 309 std::unique_ptr<Thread> dump_thread_; |
299 | 310 |
300 // The unique id of the child process. This is created only for tracing and is | 311 // The unique id of the child process. This is created only for tracing and is |
301 // expected to be valid only when tracing is enabled. | 312 // expected to be valid only when tracing is enabled. |
302 uint64_t tracing_process_id_; | 313 uint64_t tracing_process_id_; |
303 | 314 |
304 // When true, calling |RegisterMemoryDumpProvider| is a no-op. | 315 // When true, calling |RegisterMemoryDumpProvider| is a no-op. |
305 bool dumper_registrations_ignored_for_testing_; | 316 bool dumper_registrations_ignored_for_testing_; |
306 | 317 |
307 // Whether new memory dump providers should be told to enable heap profiling. | 318 // Whether new memory dump providers should be told to enable heap profiling. |
308 bool heap_profiling_enabled_; | 319 bool heap_profiling_enabled_; |
309 | 320 |
310 DISALLOW_COPY_AND_ASSIGN(MemoryDumpManager); | 321 DISALLOW_COPY_AND_ASSIGN(MemoryDumpManager); |
311 }; | 322 }; |
312 | 323 |
313 // The delegate is supposed to be long lived (read: a Singleton) and thread | |
314 // safe (i.e. should expect calls from any thread and handle thread hopping). | |
315 class BASE_EXPORT MemoryDumpManagerDelegate { | |
316 public: | |
317 MemoryDumpManagerDelegate() {} | |
318 virtual ~MemoryDumpManagerDelegate() {} | |
319 | |
320 virtual void RequestGlobalMemoryDump( | |
321 const MemoryDumpRequestArgs& args, | |
322 const GlobalMemoryDumpCallback& callback) = 0; | |
323 | |
324 virtual bool IsCoordinator() const = 0; | |
325 | |
326 protected: | |
327 void CreateProcessDump(const MemoryDumpRequestArgs& args, | |
328 const ProcessMemoryDumpCallback& callback) { | |
329 MemoryDumpManager::GetInstance()->CreateProcessDump(args, callback); | |
330 } | |
331 | |
332 private: | |
333 DISALLOW_COPY_AND_ASSIGN(MemoryDumpManagerDelegate); | |
334 }; | |
335 | |
336 } // namespace trace_event | 324 } // namespace trace_event |
337 } // namespace base | 325 } // namespace base |
338 | 326 |
339 #endif // BASE_TRACE_EVENT_MEMORY_DUMP_MANAGER_H_ | 327 #endif // BASE_TRACE_EVENT_MEMORY_DUMP_MANAGER_H_ |
OLD | NEW |