| 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 |