123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270 |
- // Copyright 2015 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #ifndef BASE_TRACE_EVENT_MEMORY_DUMP_MANAGER_H_
- #define BASE_TRACE_EVENT_MEMORY_DUMP_MANAGER_H_
- #include <stdint.h>
- #include <map>
- #include <memory>
- #include <unordered_set>
- #include <vector>
- #include "base/atomicops.h"
- #include "base/macros.h"
- #include "base/memory/ref_counted.h"
- #include "base/memory/singleton.h"
- #include "base/synchronization/lock.h"
- #include "base/trace_event/memory_allocator_dump.h"
- #include "base/trace_event/memory_dump_provider_info.h"
- #include "base/trace_event/memory_dump_request_args.h"
- #include "base/trace_event/process_memory_dump.h"
- #include "base/trace_event/trace_event.h"
- namespace base {
- class SequencedTaskRunner;
- class SingleThreadTaskRunner;
- class Thread;
- namespace trace_event {
- class MemoryDumpProvider;
- // This is the interface exposed to the rest of the codebase to deal with
- // memory tracing. The main entry point for clients is represented by
- // RequestDumpPoint(). The extension by Un(RegisterDumpProvider).
- class BASE_EXPORT MemoryDumpManager {
- public:
- using RequestGlobalDumpFunction =
- RepeatingCallback<void(MemoryDumpType, MemoryDumpLevelOfDetail)>;
- static constexpr const char* const kTraceCategory =
- TRACE_DISABLED_BY_DEFAULT("memory-infra");
- // This value is returned as the tracing id of the child processes by
- // GetTracingProcessId() when tracing is not enabled.
- static const uint64_t kInvalidTracingProcessId;
- static MemoryDumpManager* GetInstance();
- static std::unique_ptr<MemoryDumpManager> CreateInstanceForTesting();
- // Invoked once per process to listen to trace begin / end events.
- // Initialization can happen after (Un)RegisterMemoryDumpProvider() calls
- // and the MemoryDumpManager guarantees to support this.
- // On the other side, the MemoryDumpManager will not be fully operational
- // (any CreateProcessDump() will return a failure) until initialized.
- // Arguments:
- // is_coordinator: True when current process coordinates the periodic dump
- // triggering.
- // request_dump_function: Function to invoke a global dump. Global dump
- // involves embedder-specific behaviors like multiprocess handshaking.
- // TODO(primiano): this is only required to trigger global dumps from
- // the scheduler. Should be removed once they are both moved out of base.
- void Initialize(RequestGlobalDumpFunction request_dump_function,
- bool is_coordinator);
- // (Un)Registers a MemoryDumpProvider instance.
- // Args:
- // - mdp: the MemoryDumpProvider instance to be registered. MemoryDumpManager
- // does NOT take memory ownership of |mdp|, which is expected to either
- // be a singleton or unregister itself.
- // - name: a friendly name (duplicates allowed). Used for debugging and
- // run-time profiling of memory-infra internals. Must be a long-lived
- // C string.
- // - task_runner: either a SingleThreadTaskRunner or SequencedTaskRunner. All
- // the calls to |mdp| will be run on the given |task_runner|. If passed
- // null |mdp| should be able to handle calls on arbitrary threads.
- // - options: extra optional arguments. See memory_dump_provider.h.
- void RegisterDumpProvider(MemoryDumpProvider* mdp,
- const char* name,
- scoped_refptr<SingleThreadTaskRunner> task_runner);
- void RegisterDumpProvider(MemoryDumpProvider* mdp,
- const char* name,
- scoped_refptr<SingleThreadTaskRunner> task_runner,
- MemoryDumpProvider::Options options);
- void RegisterDumpProviderWithSequencedTaskRunner(
- MemoryDumpProvider* mdp,
- const char* name,
- scoped_refptr<SequencedTaskRunner> task_runner,
- MemoryDumpProvider::Options options);
- void UnregisterDumpProvider(MemoryDumpProvider* mdp);
- // Unregisters an unbound dump provider and takes care about its deletion
- // asynchronously. Can be used only for for dump providers with no
- // task-runner affinity.
- // This method takes ownership of the dump provider and guarantees that:
- // - The |mdp| will be deleted at some point in the near future.
- // - Its deletion will not happen concurrently with the OnMemoryDump() call.
- // Note that OnMemoryDump() calls can still happen after this method returns.
- void UnregisterAndDeleteDumpProviderSoon(
- std::unique_ptr<MemoryDumpProvider> mdp);
- // Prepare MemoryDumpManager for CreateProcessDump() calls for tracing-related
- // modes (i.e. |level_of_detail| != SUMMARY_ONLY).
- // Also initializes the scheduler with the given config.
- void SetupForTracing(const TraceConfig::MemoryDumpConfig&);
- // Tear-down tracing related state.
- // Non-tracing modes (e.g. SUMMARY_ONLY) will continue to work.
- void TeardownForTracing();
- // Creates a memory dump for the current process and appends it to the trace.
- // |callback| will be invoked asynchronously upon completion on the same
- // thread on which CreateProcessDump() was called. This method should only be
- // used by the memory-infra service while creating a global memory dump.
- void CreateProcessDump(const MemoryDumpRequestArgs& args,
- ProcessMemoryDumpCallback callback);
- // Lets tests see if a dump provider is registered.
- bool IsDumpProviderRegisteredForTesting(MemoryDumpProvider*);
- // Returns a unique id for identifying the processes. The id can be
- // retrieved by child processes only when tracing is enabled. This is
- // intended to express cross-process sharing of memory dumps on the
- // child-process side, without having to know its own child process id.
- uint64_t GetTracingProcessId() const { return tracing_process_id_; }
- void set_tracing_process_id(uint64_t tracing_process_id) {
- tracing_process_id_ = tracing_process_id;
- }
- // Returns the name for a the allocated_objects dump. Use this to declare
- // suballocator dumps from other dump providers.
- // It will return nullptr if there is no dump provider for the system
- // allocator registered (which is currently the case for Mac OS).
- const char* system_allocator_pool_name() const {
- return kSystemAllocatorPoolName;
- }
- // When set to true, calling |RegisterMemoryDumpProvider| is a no-op.
- void set_dumper_registrations_ignored_for_testing(bool ignored) {
- dumper_registrations_ignored_for_testing_ = ignored;
- }
- scoped_refptr<SequencedTaskRunner> GetDumpThreadTaskRunner();
- private:
- friend std::default_delete<MemoryDumpManager>; // For the testing instance.
- friend struct DefaultSingletonTraits<MemoryDumpManager>;
- friend class MemoryDumpManagerTest;
- FRIEND_TEST_ALL_PREFIXES(MemoryDumpManagerTest,
- NoStackOverflowWithTooManyMDPs);
- // Holds the state of a process memory dump that needs to be carried over
- // across task runners in order to fulfill an asynchronous CreateProcessDump()
- // request. At any time exactly one task runner owns a
- // ProcessMemoryDumpAsyncState.
- struct ProcessMemoryDumpAsyncState {
- ProcessMemoryDumpAsyncState(
- MemoryDumpRequestArgs req_args,
- const MemoryDumpProviderInfo::OrderedSet& dump_providers,
- ProcessMemoryDumpCallback callback,
- scoped_refptr<SequencedTaskRunner> dump_thread_task_runner);
- ~ProcessMemoryDumpAsyncState();
- // A ProcessMemoryDump to collect data from MemoryDumpProviders.
- std::unique_ptr<ProcessMemoryDump> process_memory_dump;
- // The arguments passed to the initial CreateProcessDump() request.
- const MemoryDumpRequestArgs req_args;
- // An ordered sequence of dump providers that have to be invoked to complete
- // the dump. This is a copy of |dump_providers_| at the beginning of a dump
- // and becomes empty at the end, when all dump providers have been invoked.
- std::vector<scoped_refptr<MemoryDumpProviderInfo>> pending_dump_providers;
- // Callback passed to the initial call to CreateProcessDump().
- ProcessMemoryDumpCallback callback;
- // The thread on which FinishAsyncProcessDump() (and hence |callback|)
- // should be invoked. This is the thread on which the initial
- // CreateProcessDump() request was called.
- const scoped_refptr<SingleThreadTaskRunner> callback_task_runner;
- // The thread on which unbound dump providers should be invoked.
- // This is essentially |dump_thread_|.task_runner() but needs to be kept
- // as a separate variable as it needs to be accessed by arbitrary dumpers'
- // threads outside of the lock_ to avoid races when disabling tracing.
- // It is immutable for all the duration of a tracing session.
- const scoped_refptr<SequencedTaskRunner> dump_thread_task_runner;
- private:
- DISALLOW_COPY_AND_ASSIGN(ProcessMemoryDumpAsyncState);
- };
- static const int kMaxConsecutiveFailuresCount;
- static const char* const kSystemAllocatorPoolName;
- MemoryDumpManager();
- virtual ~MemoryDumpManager();
- static void SetInstanceForTesting(MemoryDumpManager* instance);
- // Lazily initializes dump_thread_ and returns its TaskRunner.
- scoped_refptr<base::SequencedTaskRunner> GetOrCreateBgTaskRunnerLocked()
- EXCLUSIVE_LOCKS_REQUIRED(lock_);
- // Calls InvokeOnMemoryDump() for the each MDP that belongs to the current
- // task runner and switches to the task runner of the next MDP. Handles
- // failures in MDP and thread hops, and always calls FinishAsyncProcessDump()
- // at the end.
- void ContinueAsyncProcessDump(
- ProcessMemoryDumpAsyncState* owned_pmd_async_state);
- // Invokes OnMemoryDump() of the given MDP. Should be called on the MDP task
- // runner.
- void InvokeOnMemoryDump(MemoryDumpProviderInfo* mdpinfo,
- ProcessMemoryDump* pmd);
- void FinishAsyncProcessDump(
- std::unique_ptr<ProcessMemoryDumpAsyncState> pmd_async_state);
- // Helper for RegierDumpProvider* functions.
- void RegisterDumpProviderInternal(
- MemoryDumpProvider* mdp,
- const char* name,
- scoped_refptr<SequencedTaskRunner> task_runner,
- const MemoryDumpProvider::Options& options);
- // Helper for the public UnregisterDumpProvider* functions.
- void UnregisterDumpProviderInternal(MemoryDumpProvider* mdp,
- bool take_mdp_ownership_and_delete_async);
- bool can_request_global_dumps() const {
- return !request_dump_function_.is_null();
- }
- // An ordered set of registered MemoryDumpProviderInfo(s), sorted by task
- // runner affinity (MDPs belonging to the same task runners are adjacent).
- MemoryDumpProviderInfo::OrderedSet dump_providers_ GUARDED_BY(lock_);
- // Function provided by the embedder to handle global dump requests.
- RequestGlobalDumpFunction request_dump_function_;
- // True when current process coordinates the periodic dump triggering.
- bool is_coordinator_ GUARDED_BY(lock_);
- // Protects from concurrent accesses to the local state, eg: to guard against
- // disabling logging while dumping on another thread.
- Lock lock_;
- // Thread used for MemoryDumpProviders which don't specify a task runner
- // affinity.
- std::unique_ptr<Thread> dump_thread_ GUARDED_BY(lock_);
- // The unique id of the child process. This is created only for tracing and is
- // expected to be valid only when tracing is enabled.
- uint64_t tracing_process_id_;
- // When true, calling |RegisterMemoryDumpProvider| is a no-op.
- bool dumper_registrations_ignored_for_testing_;
- DISALLOW_COPY_AND_ASSIGN(MemoryDumpManager);
- };
- } // namespace trace_event
- } // namespace base
- #endif // BASE_TRACE_EVENT_MEMORY_DUMP_MANAGER_H_
|