Index: base/trace_event/memory_dump_manager.h |
diff --git a/base/trace_event/memory_dump_manager.h b/base/trace_event/memory_dump_manager.h |
index 3645ac18ba414e56f42c694e4a5507688dfc122d..f9ece6e14f22a5ab4ebd206ca538166caff84b65 100644 |
--- a/base/trace_event/memory_dump_manager.h |
+++ b/base/trace_event/memory_dump_manager.h |
@@ -5,7 +5,7 @@ |
#ifndef BASE_TRACE_EVENT_MEMORY_DUMP_MANAGER_H_ |
#define BASE_TRACE_EVENT_MEMORY_DUMP_MANAGER_H_ |
-#include <vector> |
+#include <set> |
#include "base/atomicops.h" |
#include "base/containers/hash_tables.h" |
@@ -14,6 +14,7 @@ |
#include "base/synchronization/lock.h" |
#include "base/timer/timer.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 { |
@@ -22,13 +23,8 @@ class SingleThreadTaskRunner; |
namespace trace_event { |
-namespace { |
-class ProcessMemoryDumpHolder; |
-} |
- |
class MemoryDumpManagerDelegate; |
class MemoryDumpProvider; |
-class ProcessMemoryDump; |
class MemoryDumpSessionState; |
// This is the interface exposed to the rest of the codebase to deal with |
@@ -36,6 +32,7 @@ class MemoryDumpSessionState; |
// RequestDumpPoint(). The extension by Un(RegisterDumpProvider). |
class BASE_EXPORT MemoryDumpManager : public TraceLog::EnabledStateObserver { |
public: |
+ static const uint64 kInvalidTracingProcessId; |
static const char* const kTraceCategoryForTesting; |
static MemoryDumpManager* GetInstance(); |
@@ -81,27 +78,97 @@ class BASE_EXPORT MemoryDumpManager : public TraceLog::EnabledStateObserver { |
return session_state_; |
} |
+ // Derives a tracing process id from a child process id. Child process ids |
+ // cannot be used directly in tracing for security reasons (see: discussion in |
+ // crrev.com/1173263004). This method is meant to be used when dumping |
+ // cross-process shared memory from a process which knows the child process id |
+ // of its endpoints. The value returned by this method is guaranteed to be |
+ // equal to the value returned by tracing_process_id() in the corresponding |
+ // child process. |
+ // This will never return kInvalidTracingProcessId. |
+ static uint64 ChildProcessIdToTracingProcessId(int child_id); |
+ |
+ // Returns a unique id for the current process. The id can be retrieved only |
+ // by child processes and 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 tracing_process_id() const { return tracing_process_id_; } |
+ |
private: |
+ friend struct DefaultDeleter<MemoryDumpManager>; // For the testing instance. |
+ friend struct DefaultSingletonTraits<MemoryDumpManager>; |
+ friend class MemoryDumpManagerDelegate; |
+ friend class MemoryDumpManagerTest; |
+ FRIEND_TEST_ALL_PREFIXES(MemoryDumpManagerTest, DisableFailingDumpers); |
+ |
// Descriptor struct used to hold information about registered MDPs. It is |
- // deliberately copyable, in order to allow to be used as hash_map value. |
+ // deliberately copyable, in order to allow it to be used as std::set value. |
struct MemoryDumpProviderInfo { |
MemoryDumpProviderInfo( |
+ MemoryDumpProvider* dump_provider, |
const scoped_refptr<SingleThreadTaskRunner>& task_runner); |
~MemoryDumpProviderInfo(); |
+ // Define a total order based on the thread (i.e. |task_runner|) affinity, |
+ // so that all MDP belonging to the same thread are adjacent in the set. |
+ bool operator<(const MemoryDumpProviderInfo& other) const; |
+ |
+ MemoryDumpProvider* const dump_provider; |
scoped_refptr<SingleThreadTaskRunner> task_runner; // Optional. |
- bool disabled; // For fail-safe logic (auto-disable failing MDPs). |
+ |
+ // For fail-safe logic (auto-disable failing MDPs). These fields are mutable |
+ // as can be safely changed without impacting the order within the set. |
+ mutable int consecutive_failures; |
+ mutable bool disabled; |
}; |
- friend struct DefaultDeleter<MemoryDumpManager>; // For the testing instance. |
- friend struct DefaultSingletonTraits<MemoryDumpManager>; |
- friend class MemoryDumpManagerDelegate; |
- friend class MemoryDumpManagerTest; |
+ using MemoryDumpProviderInfoSet = std::set<MemoryDumpProviderInfo>; |
- static void SetInstanceForTesting(MemoryDumpManager* instance); |
+ // Holds the state of a process memory dump that needs to be carried over |
+ // across threads in order to fulfil an asynchronous CreateProcessDump() |
+ // request. At any time exactly one thread owns a ProcessMemoryDumpAsyncState. |
+ struct ProcessMemoryDumpAsyncState { |
+ ProcessMemoryDumpAsyncState( |
+ MemoryDumpRequestArgs req_args, |
+ MemoryDumpProviderInfoSet::iterator next_dump_provider, |
+ const scoped_refptr<MemoryDumpSessionState>& session_state, |
+ MemoryDumpCallback callback); |
+ ~ProcessMemoryDumpAsyncState(); |
+ |
+ // The ProcessMemoryDump container, where each dump provider will dump its |
+ // own MemoryAllocatorDump(s) upon the OnMemoryDump() call. |
+ ProcessMemoryDump process_memory_dump; |
+ |
+ // The arguments passed to the initial CreateProcessDump() request. |
+ const MemoryDumpRequestArgs req_args; |
+ |
+ // The |dump_providers_| iterator to the next dump provider that should be |
+ // invoked (or dump_providers_.end() if at the end of the sequence). |
+ MemoryDumpProviderInfoSet::iterator next_dump_provider; |
+ |
+ // Callback passed to the initial call to CreateProcessDump(). |
+ MemoryDumpCallback callback; |
+ |
+ // The thread on which FinalizeDumpAndAddToTrace() (and hence |callback|) |
+ // should be invoked. This is the thread on which the initial |
+ // CreateProcessDump() request was called. |
+ const scoped_refptr<SingleThreadTaskRunner> task_runner; |
+ |
+ private: |
+ DISALLOW_COPY_AND_ASSIGN(ProcessMemoryDumpAsyncState); |
+ }; |
+ |
+ static const int kMaxConsecutiveFailuresCount; |
MemoryDumpManager(); |
- virtual ~MemoryDumpManager(); |
+ ~MemoryDumpManager() override; |
+ |
+ static void SetInstanceForTesting(MemoryDumpManager* instance); |
+ static void FinalizeDumpAndAddToTrace( |
+ scoped_ptr<ProcessMemoryDumpAsyncState> pmd_async_state); |
+ static void AbortDumpLocked(MemoryDumpCallback callback, |
+ scoped_refptr<SingleThreadTaskRunner> task_runner, |
+ uint64 dump_guid); |
// Internal, used only by MemoryDumpManagerDelegate. |
// Creates a memory dump for the current process and appends it to the trace. |
@@ -110,13 +177,25 @@ class BASE_EXPORT MemoryDumpManager : public TraceLog::EnabledStateObserver { |
void CreateProcessDump(const MemoryDumpRequestArgs& args, |
const MemoryDumpCallback& callback); |
- bool InvokeDumpProviderLocked(MemoryDumpProvider* mdp, |
- ProcessMemoryDump* pmd); |
+ // Continues the ProcessMemoryDump started by CreateProcessDump(), hopping |
+ // across threads as needed as specified by MDPs in RegisterDumpProvider(). |
void ContinueAsyncProcessDump( |
- MemoryDumpProvider* mdp, |
- scoped_refptr<ProcessMemoryDumpHolder> pmd_holder); |
+ scoped_ptr<ProcessMemoryDumpAsyncState> pmd_async_state); |
+ |
+ // Pass kInvalidTracingProcessId to invalidate the id. |
+ void set_tracing_process_id(uint64 id) { |
+ DCHECK(tracing_process_id_ == kInvalidTracingProcessId || |
+ id == kInvalidTracingProcessId || tracing_process_id_ == id); |
+ tracing_process_id_ = id; |
+ } |
+ |
+ // An ordererd set of registered MemoryDumpProviderInfo(s), sorted by thread |
+ // affinity (MDPs belonging to the same thread are adjacent). |
+ MemoryDumpProviderInfoSet dump_providers_; |
- hash_map<MemoryDumpProvider*, MemoryDumpProviderInfo> dump_providers_; |
+ // Flag used to signal that some provider was removed from |dump_providers_| |
+ // and therefore the current memory dump (if any) should be aborted. |
+ bool did_unregister_dump_provider_; |
// Shared among all the PMDs to keep state scoped to the tracing session. |
scoped_refptr<MemoryDumpSessionState> session_state_; |
@@ -134,6 +213,10 @@ class BASE_EXPORT MemoryDumpManager : public TraceLog::EnabledStateObserver { |
// For time-triggered periodic dumps. |
RepeatingTimer<MemoryDumpManager> periodic_dump_timer_; |
+ // 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 tracing_process_id_; |
+ |
// Skips the auto-registration of the core dumpers during Initialize(). |
bool skip_core_dumpers_auto_registration_for_testing_; |
@@ -160,6 +243,10 @@ class BASE_EXPORT MemoryDumpManagerDelegate { |
MemoryDumpManager::GetInstance()->CreateProcessDump(args, callback); |
} |
+ void set_tracing_process_id(uint64 id) { |
+ MemoryDumpManager::GetInstance()->set_tracing_process_id(id); |
+ } |
+ |
private: |
DISALLOW_COPY_AND_ASSIGN(MemoryDumpManagerDelegate); |
}; |