| 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 <set> | 12 #include <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/timer/timer.h" | |
| 22 #include "base/trace_event/memory_dump_request_args.h" | 21 #include "base/trace_event/memory_dump_request_args.h" |
| 23 #include "base/trace_event/process_memory_dump.h" | 22 #include "base/trace_event/process_memory_dump.h" |
| 24 #include "base/trace_event/trace_event.h" | 23 #include "base/trace_event/trace_event.h" |
| 25 | 24 |
| 26 namespace base { | 25 namespace base { |
| 27 | 26 |
| 28 class SingleThreadTaskRunner; | 27 class SingleThreadTaskRunner; |
| 29 class Thread; | 28 class Thread; |
| 30 | 29 |
| 31 namespace trace_event { | 30 namespace trace_event { |
| 32 | 31 |
| 33 class MemoryDumpManagerDelegate; | 32 class MemoryDumpManagerDelegate; |
| 34 class MemoryDumpProvider; | 33 class MemoryDumpProvider; |
| 35 class MemoryDumpSessionState; | 34 class MemoryDumpSessionState; |
| 35 class MemoryDumpTrigger; |
| 36 | 36 |
| 37 // This is the interface exposed to the rest of the codebase to deal with | 37 // This is the interface exposed to the rest of the codebase to deal with |
| 38 // memory tracing. The main entry point for clients is represented by | 38 // memory tracing. The main entry point for clients is represented by |
| 39 // RequestDumpPoint(). The extension by Un(RegisterDumpProvider). | 39 // RequestDumpPoint(). The extension by Un(RegisterDumpProvider). |
| 40 class BASE_EXPORT MemoryDumpManager : public TraceLog::EnabledStateObserver { | 40 class BASE_EXPORT MemoryDumpManager : public TraceLog::EnabledStateObserver { |
| 41 public: | 41 public: |
| 42 static const char* const kTraceCategory; | 42 static const char* const kTraceCategory; |
| 43 static const char* const kLogPrefix; | 43 static const char* const kLogPrefix; |
| 44 | 44 |
| 45 // This value is returned as the tracing id of the child processes by | 45 // This value is returned as the tracing id of the child processes by |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 145 // When set to true, calling |RegisterMemoryDumpProvider| is a no-op. | 145 // When set to true, calling |RegisterMemoryDumpProvider| is a no-op. |
| 146 void set_dumper_registrations_ignored_for_testing(bool ignored) { | 146 void set_dumper_registrations_ignored_for_testing(bool ignored) { |
| 147 dumper_registrations_ignored_for_testing_ = ignored; | 147 dumper_registrations_ignored_for_testing_ = ignored; |
| 148 } | 148 } |
| 149 | 149 |
| 150 private: | 150 private: |
| 151 friend std::default_delete<MemoryDumpManager>; // For the testing instance. | 151 friend std::default_delete<MemoryDumpManager>; // For the testing instance. |
| 152 friend struct DefaultSingletonTraits<MemoryDumpManager>; | 152 friend struct DefaultSingletonTraits<MemoryDumpManager>; |
| 153 friend class MemoryDumpManagerDelegate; | 153 friend class MemoryDumpManagerDelegate; |
| 154 friend class MemoryDumpManagerTest; | 154 friend class MemoryDumpManagerTest; |
| 155 friend class MemoryDumpTrigger; |
| 155 | 156 |
| 156 // Descriptor used to hold information about registered MDPs. | 157 // Descriptor used to hold information about registered MDPs. |
| 157 // Some important considerations about lifetime of this object: | 158 // Some important considerations about lifetime of this object: |
| 158 // - In nominal conditions, all the MemoryDumpProviderInfo instances live in | 159 // - In nominal conditions, all the MemoryDumpProviderInfo instances live in |
| 159 // the |dump_providers_| collection (% unregistration while dumping). | 160 // the |dump_providers_| collection (% unregistration while dumping). |
| 160 // - Upon each dump they (actually their scoped_refptr-s) are copied into | 161 // - Upon each dump they (actually their scoped_refptr-s) are copied into |
| 161 // the ProcessMemoryDumpAsyncState. This is to allow removal (see below). | 162 // the ProcessMemoryDumpAsyncState. This is to allow removal (see below). |
| 162 // - When the MDP.OnMemoryDump() is invoked, the corresponding MDPInfo copy | 163 // - When the MDP.OnMemoryDump() is invoked, the corresponding MDPInfo copy |
| 163 // inside ProcessMemoryDumpAsyncState is removed. | 164 // inside ProcessMemoryDumpAsyncState is removed. |
| 164 // - In most cases, the MDPInfo is destroyed within UnregisterDumpProvider(). | 165 // - In most cases, the MDPInfo is destroyed within UnregisterDumpProvider(). |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 267 // This is essentially |dump_thread_|.task_runner() but needs to be kept | 268 // This is essentially |dump_thread_|.task_runner() but needs to be kept |
| 268 // as a separate variable as it needs to be accessed by arbitrary dumpers' | 269 // as a separate variable as it needs to be accessed by arbitrary dumpers' |
| 269 // threads outside of the lock_ to avoid races when disabling tracing. | 270 // threads outside of the lock_ to avoid races when disabling tracing. |
| 270 // It is immutable for all the duration of a tracing session. | 271 // It is immutable for all the duration of a tracing session. |
| 271 const scoped_refptr<SingleThreadTaskRunner> dump_thread_task_runner; | 272 const scoped_refptr<SingleThreadTaskRunner> dump_thread_task_runner; |
| 272 | 273 |
| 273 private: | 274 private: |
| 274 DISALLOW_COPY_AND_ASSIGN(ProcessMemoryDumpAsyncState); | 275 DISALLOW_COPY_AND_ASSIGN(ProcessMemoryDumpAsyncState); |
| 275 }; | 276 }; |
| 276 | 277 |
| 277 // Sets up periodic memory dump timers to start global dump requests based on | |
| 278 // the dump triggers from trace config. | |
| 279 class BASE_EXPORT PeriodicGlobalDumpTimer { | |
| 280 public: | |
| 281 PeriodicGlobalDumpTimer(); | |
| 282 ~PeriodicGlobalDumpTimer(); | |
| 283 | |
| 284 void Start(const std::vector<TraceConfig::MemoryDumpConfig::Trigger>& | |
| 285 triggers_list); | |
| 286 void Stop(); | |
| 287 | |
| 288 bool IsRunning(); | |
| 289 | |
| 290 private: | |
| 291 // Periodically called by the timer. | |
| 292 void RequestPeriodicGlobalDump(); | |
| 293 | |
| 294 RepeatingTimer timer_; | |
| 295 uint32_t periodic_dumps_count_; | |
| 296 uint32_t light_dump_rate_; | |
| 297 uint32_t heavy_dump_rate_; | |
| 298 | |
| 299 DISALLOW_COPY_AND_ASSIGN(PeriodicGlobalDumpTimer); | |
| 300 }; | |
| 301 | |
| 302 static const int kMaxConsecutiveFailuresCount; | 278 static const int kMaxConsecutiveFailuresCount; |
| 303 static const char* const kSystemAllocatorPoolName; | 279 static const char* const kSystemAllocatorPoolName; |
| 304 | 280 |
| 305 MemoryDumpManager(); | 281 MemoryDumpManager(); |
| 306 ~MemoryDumpManager() override; | 282 ~MemoryDumpManager() override; |
| 307 | 283 |
| 308 static void SetInstanceForTesting(MemoryDumpManager* instance); | 284 static void SetInstanceForTesting(MemoryDumpManager* instance); |
| 309 static void FinalizeDumpAndAddToTrace( | 285 static void FinalizeDumpAndAddToTrace( |
| 310 std::unique_ptr<ProcessMemoryDumpAsyncState> pmd_async_state); | 286 std::unique_ptr<ProcessMemoryDumpAsyncState> pmd_async_state); |
| 311 | 287 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 328 // Invokes OnMemoryDump() of the next MDP and calls SetupNextMemoryDump() at | 304 // Invokes OnMemoryDump() of the next MDP and calls SetupNextMemoryDump() at |
| 329 // the end to continue the ProcessMemoryDump. Should be called on the MDP task | 305 // the end to continue the ProcessMemoryDump. Should be called on the MDP task |
| 330 // runner. | 306 // runner. |
| 331 void InvokeOnMemoryDump(ProcessMemoryDumpAsyncState* owned_pmd_async_state); | 307 void InvokeOnMemoryDump(ProcessMemoryDumpAsyncState* owned_pmd_async_state); |
| 332 | 308 |
| 333 // Records a quick total memory usage in |memory_total|. This is used to track | 309 // Records a quick total memory usage in |memory_total|. This is used to track |
| 334 // and detect peaks in the memory usage of the process without having to | 310 // and detect peaks in the memory usage of the process without having to |
| 335 // record all data from dump providers. This value is approximate to trade-off | 311 // record all data from dump providers. This value is approximate to trade-off |
| 336 // speed, and not consistent with the rest of the memory-infra metrics. Must | 312 // speed, and not consistent with the rest of the memory-infra metrics. Must |
| 337 // be called on the dump thread. | 313 // be called on the dump thread. |
| 338 void PollFastMemoryTotal(uint64_t* memory_total); | 314 // Returns true if |memory_total| was updated by polling at least 1 MDP. |
| 315 bool PollFastMemoryTotal(uint64_t* memory_total); |
| 339 | 316 |
| 340 // Helper for RegierDumpProvider* functions. | 317 // Helper for RegierDumpProvider* functions. |
| 341 void RegisterDumpProviderInternal( | 318 void RegisterDumpProviderInternal( |
| 342 MemoryDumpProvider* mdp, | 319 MemoryDumpProvider* mdp, |
| 343 const char* name, | 320 const char* name, |
| 344 scoped_refptr<SequencedTaskRunner> task_runner, | 321 scoped_refptr<SequencedTaskRunner> task_runner, |
| 345 const MemoryDumpProvider::Options& options); | 322 const MemoryDumpProvider::Options& options); |
| 346 | 323 |
| 347 // Helper for the public UnregisterDumpProvider* functions. | 324 // Helper for the public UnregisterDumpProvider* functions. |
| 348 void UnregisterDumpProviderInternal(MemoryDumpProvider* mdp, | 325 void UnregisterDumpProviderInternal(MemoryDumpProvider* mdp, |
| (...skipping 12 matching lines...) Expand all Loading... |
| 361 | 338 |
| 362 // A copy of mdpinfo list that support polling. It must be accessed only on | 339 // A copy of mdpinfo list that support polling. It must be accessed only on |
| 363 // the dump thread if dump thread exists. | 340 // the dump thread if dump thread exists. |
| 364 MemoryDumpProviderInfo::OrderedSet dump_providers_for_polling_; | 341 MemoryDumpProviderInfo::OrderedSet dump_providers_for_polling_; |
| 365 | 342 |
| 366 // Shared among all the PMDs to keep state scoped to the tracing session. | 343 // Shared among all the PMDs to keep state scoped to the tracing session. |
| 367 scoped_refptr<MemoryDumpSessionState> session_state_; | 344 scoped_refptr<MemoryDumpSessionState> session_state_; |
| 368 | 345 |
| 369 MemoryDumpManagerDelegate* delegate_; // Not owned. | 346 MemoryDumpManagerDelegate* delegate_; // Not owned. |
| 370 | 347 |
| 371 // When true, this instance is in charge of coordinating periodic dumps. | |
| 372 bool is_coordinator_; | |
| 373 | |
| 374 // Protects from concurrent accesses to the |dump_providers_*| and |delegate_| | 348 // Protects from concurrent accesses to the |dump_providers_*| and |delegate_| |
| 375 // to guard against disabling logging while dumping on another thread. | 349 // to guard against disabling logging while dumping on another thread. |
| 376 Lock lock_; | 350 Lock lock_; |
| 377 | 351 |
| 378 // Optimization to avoid attempting any memory dump (i.e. to not walk an empty | 352 // Optimization to avoid attempting any memory dump (i.e. to not walk an empty |
| 379 // dump_providers_enabled_ list) when tracing is not enabled. | 353 // dump_providers_enabled_ list) when tracing is not enabled. |
| 380 subtle::AtomicWord memory_tracing_enabled_; | 354 subtle::AtomicWord memory_tracing_enabled_; |
| 381 | 355 |
| 382 // For time-triggered periodic dumps. | 356 // For triggering memory dumps. |
| 383 PeriodicGlobalDumpTimer periodic_dump_timer_; | 357 std::unique_ptr<MemoryDumpTrigger> dump_trigger_; |
| 384 | 358 |
| 385 // Thread used for MemoryDumpProviders which don't specify a task runner | 359 // Thread used for MemoryDumpProviders which don't specify a task runner |
| 386 // affinity. | 360 // affinity. |
| 387 std::unique_ptr<Thread> dump_thread_; | 361 std::unique_ptr<Thread> dump_thread_; |
| 388 | 362 |
| 389 // The unique id of the child process. This is created only for tracing and is | 363 // The unique id of the child process. This is created only for tracing and is |
| 390 // expected to be valid only when tracing is enabled. | 364 // expected to be valid only when tracing is enabled. |
| 391 uint64_t tracing_process_id_; | 365 uint64_t tracing_process_id_; |
| 392 | 366 |
| 393 // When true, calling |RegisterMemoryDumpProvider| is a no-op. | 367 // When true, calling |RegisterMemoryDumpProvider| is a no-op. |
| (...skipping 26 matching lines...) Expand all Loading... |
| 420 } | 394 } |
| 421 | 395 |
| 422 private: | 396 private: |
| 423 DISALLOW_COPY_AND_ASSIGN(MemoryDumpManagerDelegate); | 397 DISALLOW_COPY_AND_ASSIGN(MemoryDumpManagerDelegate); |
| 424 }; | 398 }; |
| 425 | 399 |
| 426 } // namespace trace_event | 400 } // namespace trace_event |
| 427 } // namespace base | 401 } // namespace base |
| 428 | 402 |
| 429 #endif // BASE_TRACE_EVENT_MEMORY_DUMP_MANAGER_H_ | 403 #endif // BASE_TRACE_EVENT_MEMORY_DUMP_MANAGER_H_ |
| OLD | NEW |