Chromium Code Reviews| 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 |