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> |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 62 void Initialize(MemoryDumpManagerDelegate* delegate, bool is_coordinator); | 62 void Initialize(MemoryDumpManagerDelegate* delegate, bool is_coordinator); |
| 63 | 63 |
| 64 // (Un)Registers a MemoryDumpProvider instance. | 64 // (Un)Registers a MemoryDumpProvider instance. |
| 65 // Args: | 65 // Args: |
| 66 // - mdp: the MemoryDumpProvider instance to be registered. MemoryDumpManager | 66 // - mdp: the MemoryDumpProvider instance to be registered. MemoryDumpManager |
| 67 // does NOT take memory ownership of |mdp|, which is expected to either | 67 // does NOT take memory ownership of |mdp|, which is expected to either |
| 68 // be a singleton or unregister itself. | 68 // be a singleton or unregister itself. |
| 69 // - name: a friendly name (duplicates allowed). Used for debugging and | 69 // - name: a friendly name (duplicates allowed). Used for debugging and |
| 70 // run-time profiling of memory-infra internals. Must be a long-lived | 70 // run-time profiling of memory-infra internals. Must be a long-lived |
| 71 // C string. | 71 // C string. |
| 72 // - task_runner: if non-null, all the calls to |mdp| will be | 72 // - task_runner: either a SingleThreadTaskRunner or SequencedTaskRunner. All |
| 73 // issued on the given thread. Otherwise, |mdp| should be able to | 73 // the calls to |mdp| will be run on the given |task_runner|. |
| 74 // handle calls on arbitrary threads. | 74 // RegisterDumpProviderWithSequencedTaskRunner does not accept null |
| 75 // |task_runner|, otherwise if passed null |mdp| should be able to handle | |
|
Primiano Tucci (use gerrit)
2016/02/08 12:03:15
I'd make this comment a bit simpler and skip the p
ssid
2016/02/11 01:45:03
Done.
| |
| 76 // calls on arbitrary threads. | |
| 75 // - options: extra optional arguments. See memory_dump_provider.h. | 77 // - options: extra optional arguments. See memory_dump_provider.h. |
| 76 void RegisterDumpProvider( | 78 void RegisterDumpProvider( |
| 77 MemoryDumpProvider* mdp, | 79 MemoryDumpProvider* mdp, |
| 78 const char* name, | 80 const char* name, |
| 79 const scoped_refptr<SingleThreadTaskRunner>& task_runner); | 81 const scoped_refptr<SingleThreadTaskRunner>& task_runner); |
| 80 void RegisterDumpProvider( | 82 void RegisterDumpProvider( |
| 81 MemoryDumpProvider* mdp, | 83 MemoryDumpProvider* mdp, |
| 82 const char* name, | 84 const char* name, |
| 83 const scoped_refptr<SingleThreadTaskRunner>& task_runner, | 85 const scoped_refptr<SingleThreadTaskRunner>& task_runner, |
| 84 const MemoryDumpProvider::Options& options); | 86 MemoryDumpProvider::Options options); |
| 87 void RegisterDumpProviderWithSequencedTaskRunner( | |
| 88 MemoryDumpProvider* mdp, | |
| 89 const char* name, | |
| 90 const scoped_refptr<SequencedTaskRunner>& task_runner, | |
| 91 MemoryDumpProvider::Options options); | |
| 85 void UnregisterDumpProvider(MemoryDumpProvider* mdp); | 92 void UnregisterDumpProvider(MemoryDumpProvider* mdp); |
| 86 | 93 |
| 87 // Unregisters an unbound dump provider and takes care about its deletion | 94 // Unregisters an unbound dump provider and takes care about its deletion |
| 88 // asynchronously. Can be used only for for dump providers with no | 95 // asynchronously. Can be used only for for dump providers with no |
| 89 // task-runner affinity. | 96 // task-runner affinity. |
| 90 // This method takes ownership of the dump provider and guarantees that: | 97 // This method takes ownership of the dump provider and guarantees that: |
| 91 // - The |mdp| will be deleted at some point in the near future. | 98 // - The |mdp| will be deleted at some point in the near future. |
| 92 // - Its deletion will not happen concurrently with the OnMemoryDump() call. | 99 // - Its deletion will not happen concurrently with the OnMemoryDump() call. |
| 93 // Note that OnMemoryDump() calls can still happen after this method returns. | 100 // Note that OnMemoryDump() calls can still happen after this method returns. |
| 94 void UnregisterAndDeleteDumpProviderSoon(scoped_ptr<MemoryDumpProvider> mdp); | 101 void UnregisterAndDeleteDumpProviderSoon(scoped_ptr<MemoryDumpProvider> mdp); |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 146 // Descriptor used to hold information about registered MDPs. | 153 // Descriptor used to hold information about registered MDPs. |
| 147 // Some important considerations about lifetime of this object: | 154 // Some important considerations about lifetime of this object: |
| 148 // - In nominal conditions, all the MemoryDumpProviderInfo instances live in | 155 // - In nominal conditions, all the MemoryDumpProviderInfo instances live in |
| 149 // the |dump_providers_| collection (% unregistration while dumping). | 156 // the |dump_providers_| collection (% unregistration while dumping). |
| 150 // - Upon each dump they (actually their scoped_refptr-s) are copied into | 157 // - Upon each dump they (actually their scoped_refptr-s) are copied into |
| 151 // the ProcessMemoryDumpAsyncState. This is to allow removal (see below). | 158 // the ProcessMemoryDumpAsyncState. This is to allow removal (see below). |
| 152 // - When the MDP.OnMemoryDump() is invoked, the corresponding MDPInfo copy | 159 // - When the MDP.OnMemoryDump() is invoked, the corresponding MDPInfo copy |
| 153 // inside ProcessMemoryDumpAsyncState is removed. | 160 // inside ProcessMemoryDumpAsyncState is removed. |
| 154 // - In most cases, the MDPInfo is destroyed within UnregisterDumpProvider(). | 161 // - In most cases, the MDPInfo is destroyed within UnregisterDumpProvider(). |
| 155 // - If UnregisterDumpProvider() is called while a dump is in progress, the | 162 // - If UnregisterDumpProvider() is called while a dump is in progress, the |
| 156 // MDPInfo is destroyed in the epilogue of ContinueAsyncProcessDump(), when | 163 // MDPInfo is destroyed in the epilogue of SetupNextMemoryDump(), when |
| 157 // the copy inside ProcessMemoryDumpAsyncState is erase()-d. | 164 // the copy inside ProcessMemoryDumpAsyncState is erase()-d. |
| 158 // - The non-const fields of MemoryDumpProviderInfo are safe to access only | 165 // - The non-const fields of MemoryDumpProviderInfo are safe to access only |
| 159 // in the |task_runner| thread, unless the thread has been destroyed. | 166 // on tasks running in the |task_runner|, unless the thread has been |
| 167 // destroyed. | |
| 160 struct MemoryDumpProviderInfo | 168 struct MemoryDumpProviderInfo |
| 161 : public RefCountedThreadSafe<MemoryDumpProviderInfo> { | 169 : public RefCountedThreadSafe<MemoryDumpProviderInfo> { |
| 162 // Define a total order based on the thread (i.e. |task_runner|) affinity, | 170 // Define a total order based on the |task_runner| affinity, so that MDPs |
| 163 // so that all MDP belonging to the same thread are adjacent in the set. | 171 // belonging to the same SequencedTaskRunner are adjacent in the set. |
| 164 struct Comparator { | 172 struct Comparator { |
| 165 bool operator()(const scoped_refptr<MemoryDumpProviderInfo>& a, | 173 bool operator()(const scoped_refptr<MemoryDumpProviderInfo>& a, |
| 166 const scoped_refptr<MemoryDumpProviderInfo>& b) const; | 174 const scoped_refptr<MemoryDumpProviderInfo>& b) const; |
| 167 }; | 175 }; |
| 168 using OrderedSet = | 176 using OrderedSet = |
| 169 std::set<scoped_refptr<MemoryDumpProviderInfo>, Comparator>; | 177 std::set<scoped_refptr<MemoryDumpProviderInfo>, Comparator>; |
| 170 | 178 |
| 171 MemoryDumpProviderInfo( | 179 MemoryDumpProviderInfo( |
| 172 MemoryDumpProvider* dump_provider, | 180 MemoryDumpProvider* dump_provider, |
| 173 const char* name, | 181 const char* name, |
| 174 const scoped_refptr<SingleThreadTaskRunner>& task_runner, | 182 const scoped_refptr<SequencedTaskRunner>& task_runner, |
| 175 const MemoryDumpProvider::Options& options); | 183 const MemoryDumpProvider::Options& options); |
| 176 | 184 |
| 177 MemoryDumpProvider* const dump_provider; | 185 MemoryDumpProvider* const dump_provider; |
| 178 | 186 |
| 179 // Used to transfer ownership for UnregisterAndDeleteDumpProviderSoon(). | 187 // Used to transfer ownership for UnregisterAndDeleteDumpProviderSoon(). |
| 180 // nullptr in all other cases. | 188 // nullptr in all other cases. |
| 181 scoped_ptr<MemoryDumpProvider> owned_dump_provider; | 189 scoped_ptr<MemoryDumpProvider> owned_dump_provider; |
| 182 | 190 |
| 183 // Human readable name, for debugging and testing. Not necessarily unique. | 191 // Human readable name, for debugging and testing. Not necessarily unique. |
| 184 const char* const name; | 192 const char* const name; |
| 185 | 193 |
| 186 // The task_runner affinity. Can be nullptr, in which case the dump provider | 194 // The task runner affinity. Can be nullptr, in which case the dump provider |
| 187 // will be invoked on |dump_thread_|. | 195 // will be invoked on |dump_thread_|. |
| 188 const scoped_refptr<SingleThreadTaskRunner> task_runner; | 196 const scoped_refptr<SequencedTaskRunner> task_runner; |
| 189 | 197 |
| 190 // The |options| arg passed to RegisterDumpProvider(). | 198 // The |options| arg passed to RegisterDumpProvider(). |
| 191 const MemoryDumpProvider::Options options; | 199 const MemoryDumpProvider::Options options; |
| 192 | 200 |
| 193 // For fail-safe logic (auto-disable failing MDPs). | 201 // For fail-safe logic (auto-disable failing MDPs). |
| 194 int consecutive_failures; | 202 int consecutive_failures; |
| 195 | 203 |
| 196 // Flagged either by the auto-disable logic or during unregistration. | 204 // Flagged either by the auto-disable logic or during unregistration. |
| 197 bool disabled; | 205 bool disabled; |
| 198 | 206 |
| 199 private: | 207 private: |
| 200 friend class base::RefCountedThreadSafe<MemoryDumpProviderInfo>; | 208 friend class base::RefCountedThreadSafe<MemoryDumpProviderInfo>; |
| 201 ~MemoryDumpProviderInfo(); | 209 ~MemoryDumpProviderInfo(); |
| 202 | 210 |
| 203 DISALLOW_COPY_AND_ASSIGN(MemoryDumpProviderInfo); | 211 DISALLOW_COPY_AND_ASSIGN(MemoryDumpProviderInfo); |
| 204 }; | 212 }; |
| 205 | 213 |
| 206 // Holds the state of a process memory dump that needs to be carried over | 214 // Holds the state of a process memory dump that needs to be carried over |
| 207 // across threads in order to fulfil an asynchronous CreateProcessDump() | 215 // across task runners in order to fulfil an asynchronous CreateProcessDump() |
| 208 // request. At any time exactly one thread owns a ProcessMemoryDumpAsyncState. | 216 // request. At any time exactly one task runner owns a |
| 217 // ProcessMemoryDumpAsyncState. | |
| 209 struct ProcessMemoryDumpAsyncState { | 218 struct ProcessMemoryDumpAsyncState { |
| 210 ProcessMemoryDumpAsyncState( | 219 ProcessMemoryDumpAsyncState( |
| 211 MemoryDumpRequestArgs req_args, | 220 MemoryDumpRequestArgs req_args, |
| 212 const MemoryDumpProviderInfo::OrderedSet& dump_providers, | 221 const MemoryDumpProviderInfo::OrderedSet& dump_providers, |
| 213 const scoped_refptr<MemoryDumpSessionState>& session_state, | 222 const scoped_refptr<MemoryDumpSessionState>& session_state, |
| 214 MemoryDumpCallback callback, | 223 MemoryDumpCallback callback, |
| 215 const scoped_refptr<SingleThreadTaskRunner>& dump_thread_task_runner); | 224 const scoped_refptr<SingleThreadTaskRunner>& dump_thread_task_runner); |
| 216 ~ProcessMemoryDumpAsyncState(); | 225 ~ProcessMemoryDumpAsyncState(); |
| 217 | 226 |
| 218 // Gets or creates the memory dump container for the given target process. | 227 // Gets or creates the memory dump container for the given target process. |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 242 bool dump_successful; | 251 bool dump_successful; |
| 243 | 252 |
| 244 // The thread on which FinalizeDumpAndAddToTrace() (and hence |callback|) | 253 // The thread on which FinalizeDumpAndAddToTrace() (and hence |callback|) |
| 245 // should be invoked. This is the thread on which the initial | 254 // should be invoked. This is the thread on which the initial |
| 246 // CreateProcessDump() request was called. | 255 // CreateProcessDump() request was called. |
| 247 const scoped_refptr<SingleThreadTaskRunner> callback_task_runner; | 256 const scoped_refptr<SingleThreadTaskRunner> callback_task_runner; |
| 248 | 257 |
| 249 // The thread on which unbound dump providers should be invoked. | 258 // The thread on which unbound dump providers should be invoked. |
| 250 // This is essentially |dump_thread_|.task_runner() but needs to be kept | 259 // This is essentially |dump_thread_|.task_runner() but needs to be kept |
| 251 // as a separate variable as it needs to be accessed by arbitrary dumpers' | 260 // as a separate variable as it needs to be accessed by arbitrary dumpers' |
| 252 // threads outside of the lock_ to avoid races when disabling tracing. | 261 // task runners outside of the lock_ to avoid races when disabling tracing. |
|
Primiano Tucci (use gerrit)
2016/02/08 12:03:15
keep this as thread, task_runner doesn't add a lot
ssid
2016/02/11 01:45:03
Done.
| |
| 253 // It is immutable for all the duration of a tracing session. | 262 // It is immutable for all the duration of a tracing session. |
| 254 const scoped_refptr<SingleThreadTaskRunner> dump_thread_task_runner; | 263 const scoped_refptr<SingleThreadTaskRunner> dump_thread_task_runner; |
| 255 | 264 |
| 256 private: | 265 private: |
| 257 DISALLOW_COPY_AND_ASSIGN(ProcessMemoryDumpAsyncState); | 266 DISALLOW_COPY_AND_ASSIGN(ProcessMemoryDumpAsyncState); |
| 258 }; | 267 }; |
| 259 | 268 |
| 260 static const int kMaxConsecutiveFailuresCount; | 269 static const int kMaxConsecutiveFailuresCount; |
| 261 static const char* const kSystemAllocatorPoolName; | 270 static const char* const kSystemAllocatorPoolName; |
| 262 | 271 |
| 263 MemoryDumpManager(); | 272 MemoryDumpManager(); |
| 264 ~MemoryDumpManager() override; | 273 ~MemoryDumpManager() override; |
| 265 | 274 |
| 266 static void SetInstanceForTesting(MemoryDumpManager* instance); | 275 static void SetInstanceForTesting(MemoryDumpManager* instance); |
| 267 static void FinalizeDumpAndAddToTrace( | 276 static void FinalizeDumpAndAddToTrace( |
| 268 scoped_ptr<ProcessMemoryDumpAsyncState> pmd_async_state); | 277 scoped_ptr<ProcessMemoryDumpAsyncState> pmd_async_state); |
| 269 | 278 |
| 270 // Enable heap profiling if kEnableHeapProfiling is specified. | 279 // Enable heap profiling if kEnableHeapProfiling is specified. |
| 271 void EnableHeapProfilingIfNeeded(); | 280 void EnableHeapProfilingIfNeeded(); |
| 272 | 281 |
| 273 // Internal, used only by MemoryDumpManagerDelegate. | 282 // Internal, used only by MemoryDumpManagerDelegate. |
| 274 // Creates a memory dump for the current process and appends it to the trace. | 283 // Creates a memory dump for the current process and appends it to the trace. |
| 275 // |callback| will be invoked asynchronously upon completion on the same | 284 // |callback| will be invoked asynchronously upon completion on the same |
| 276 // thread on which CreateProcessDump() was called. | 285 // thread on which CreateProcessDump() was called. |
| 277 void CreateProcessDump(const MemoryDumpRequestArgs& args, | 286 void CreateProcessDump(const MemoryDumpRequestArgs& args, |
| 278 const MemoryDumpCallback& callback); | 287 const MemoryDumpCallback& callback); |
| 279 | 288 |
| 280 // Continues the ProcessMemoryDump started by CreateProcessDump(), hopping | 289 // SetupNextMemoryDump, InvokeOnMemoryDump and FinalizeCurrentDump are called |
| 281 // across threads as needed as specified by MDPs in RegisterDumpProvider(). | 290 // in order for each dump provider to obtain a memory dump: |
| 282 void ContinueAsyncProcessDump( | 291 |
| 283 ProcessMemoryDumpAsyncState* owned_pmd_async_state); | 292 // Calls InvokeOnMemoryDump for the next MDP on the task runner specified by |
| 293 // the MDP while registration. On failure to do so, calls FinalizeCurrentDump | |
| 294 // directly. | |
| 295 void SetupNextMemoryDump( | |
| 296 scoped_ptr<ProcessMemoryDumpAsyncState> pmd_async_state); | |
| 297 | |
| 298 // Invokes OnMemoryDump of the last MDP and calls FinalizeCurrentDump. Should | |
|
Primiano Tucci (use gerrit)
2016/02/08 12:03:15
remove "of the last MDP" it's really misleading.
I
ssid
2016/02/11 01:45:03
Done.
| |
| 299 // be called on the MDP task runner. | |
| 300 void InvokeOnMemoryDump(ProcessMemoryDumpAsyncState* owned_pmd_async_state); | |
| 301 | |
| 302 // Finishes current dump and calls either SetupNextMemoryDump for next dump | |
| 303 // provider or FinalizeDumpAndAddToTrace if we covered all providers. | |
| 304 void FinalizeCurrentDump( | |
| 305 scoped_ptr<ProcessMemoryDumpAsyncState> pmd_async_state); | |
| 306 | |
| 307 // Helper for RegierDumpProvider* functions. | |
| 308 void RegisterDumpProviderInternal( | |
| 309 MemoryDumpProvider* mdp, | |
| 310 const char* name, | |
| 311 const scoped_refptr<SequencedTaskRunner>& task_runner, | |
| 312 const MemoryDumpProvider::Options& options); | |
| 284 | 313 |
| 285 // Helper for the public UnregisterDumpProvider* functions. | 314 // Helper for the public UnregisterDumpProvider* functions. |
| 286 void UnregisterDumpProviderInternal(MemoryDumpProvider* mdp, | 315 void UnregisterDumpProviderInternal(MemoryDumpProvider* mdp, |
| 287 bool take_mdp_ownership_and_delete_async); | 316 bool take_mdp_ownership_and_delete_async); |
| 288 | 317 |
| 289 // An ordererd set of registered MemoryDumpProviderInfo(s), sorted by thread | 318 // An ordererd set of registered MemoryDumpProviderInfo(s), sorted by task |
| 290 // affinity (MDPs belonging to the same thread are adjacent). | 319 // runner affinity (MDPs belonging to the same task runners are adjacent). |
| 291 MemoryDumpProviderInfo::OrderedSet dump_providers_; | 320 MemoryDumpProviderInfo::OrderedSet dump_providers_; |
| 292 | 321 |
| 293 // Shared among all the PMDs to keep state scoped to the tracing session. | 322 // Shared among all the PMDs to keep state scoped to the tracing session. |
| 294 scoped_refptr<MemoryDumpSessionState> session_state_; | 323 scoped_refptr<MemoryDumpSessionState> session_state_; |
| 295 | 324 |
| 296 MemoryDumpManagerDelegate* delegate_; // Not owned. | 325 MemoryDumpManagerDelegate* delegate_; // Not owned. |
| 297 | 326 |
| 298 // When true, this instance is in charge of coordinating periodic dumps. | 327 // When true, this instance is in charge of coordinating periodic dumps. |
| 299 bool is_coordinator_; | 328 bool is_coordinator_; |
| 300 | 329 |
| 301 // Protects from concurrent accesses to the |dump_providers_*| and |delegate_| | 330 // Protects from concurrent accesses to the |dump_providers_*| and |delegate_| |
| 302 // to guard against disabling logging while dumping on another thread. | 331 // to guard against disabling logging while dumping on another thread. |
| 303 Lock lock_; | 332 Lock lock_; |
| 304 | 333 |
| 305 // Optimization to avoid attempting any memory dump (i.e. to not walk an empty | 334 // Optimization to avoid attempting any memory dump (i.e. to not walk an empty |
| 306 // dump_providers_enabled_ list) when tracing is not enabled. | 335 // dump_providers_enabled_ list) when tracing is not enabled. |
| 307 subtle::AtomicWord memory_tracing_enabled_; | 336 subtle::AtomicWord memory_tracing_enabled_; |
| 308 | 337 |
| 309 // For time-triggered periodic dumps. | 338 // For time-triggered periodic dumps. |
| 310 RepeatingTimer periodic_dump_timer_; | 339 RepeatingTimer periodic_dump_timer_; |
| 311 | 340 |
| 312 // Thread used for MemoryDumpProviders which don't specify a thread affinity. | 341 // Thread used for MemoryDumpProviders which don't specify a task runner |
| 342 // affinity. | |
| 313 scoped_ptr<Thread> dump_thread_; | 343 scoped_ptr<Thread> dump_thread_; |
| 314 | 344 |
| 315 // The unique id of the child process. This is created only for tracing and is | 345 // The unique id of the child process. This is created only for tracing and is |
| 316 // expected to be valid only when tracing is enabled. | 346 // expected to be valid only when tracing is enabled. |
| 317 uint64_t tracing_process_id_; | 347 uint64_t tracing_process_id_; |
| 318 | 348 |
| 319 // When true, calling |RegisterMemoryDumpProvider| is a no-op. | 349 // When true, calling |RegisterMemoryDumpProvider| is a no-op. |
| 320 bool dumper_registrations_ignored_for_testing_; | 350 bool dumper_registrations_ignored_for_testing_; |
| 321 | 351 |
| 322 // Whether new memory dump providers should be told to enable heap profiling. | 352 // Whether new memory dump providers should be told to enable heap profiling. |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 346 } | 376 } |
| 347 | 377 |
| 348 private: | 378 private: |
| 349 DISALLOW_COPY_AND_ASSIGN(MemoryDumpManagerDelegate); | 379 DISALLOW_COPY_AND_ASSIGN(MemoryDumpManagerDelegate); |
| 350 }; | 380 }; |
| 351 | 381 |
| 352 } // namespace trace_event | 382 } // namespace trace_event |
| 353 } // namespace base | 383 } // namespace base |
| 354 | 384 |
| 355 #endif // BASE_TRACE_EVENT_MEMORY_DUMP_MANAGER_H_ | 385 #endif // BASE_TRACE_EVENT_MEMORY_DUMP_MANAGER_H_ |
| OLD | NEW |