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 <vector> | 8 #include <set> |
9 | 9 |
10 #include "base/atomicops.h" | 10 #include "base/atomicops.h" |
11 #include "base/containers/hash_tables.h" | 11 #include "base/containers/hash_tables.h" |
12 #include "base/memory/ref_counted.h" | 12 #include "base/memory/ref_counted.h" |
13 #include "base/memory/singleton.h" | 13 #include "base/memory/singleton.h" |
14 #include "base/synchronization/lock.h" | 14 #include "base/synchronization/lock.h" |
15 #include "base/timer/timer.h" | 15 #include "base/timer/timer.h" |
16 #include "base/trace_event/memory_dump_request_args.h" | 16 #include "base/trace_event/memory_dump_request_args.h" |
| 17 #include "base/trace_event/process_memory_dump.h" |
17 #include "base/trace_event/trace_event.h" | 18 #include "base/trace_event/trace_event.h" |
18 | 19 |
19 namespace base { | 20 namespace base { |
20 | 21 |
21 class SingleThreadTaskRunner; | 22 class SingleThreadTaskRunner; |
22 | 23 |
23 namespace trace_event { | 24 namespace trace_event { |
24 | 25 |
25 namespace { | |
26 class ProcessMemoryDumpHolder; | |
27 } | |
28 | |
29 class MemoryDumpManagerDelegate; | 26 class MemoryDumpManagerDelegate; |
30 class MemoryDumpProvider; | 27 class MemoryDumpProvider; |
31 class ProcessMemoryDump; | |
32 class MemoryDumpSessionState; | 28 class MemoryDumpSessionState; |
33 | 29 |
34 // This is the interface exposed to the rest of the codebase to deal with | 30 // This is the interface exposed to the rest of the codebase to deal with |
35 // memory tracing. The main entry point for clients is represented by | 31 // memory tracing. The main entry point for clients is represented by |
36 // RequestDumpPoint(). The extension by Un(RegisterDumpProvider). | 32 // RequestDumpPoint(). The extension by Un(RegisterDumpProvider). |
37 class BASE_EXPORT MemoryDumpManager : public TraceLog::EnabledStateObserver { | 33 class BASE_EXPORT MemoryDumpManager : public TraceLog::EnabledStateObserver { |
38 public: | 34 public: |
39 static const uint64 kInvalidTracingProcessId; | 35 static const uint64 kInvalidTracingProcessId; |
40 static const char* const kTraceCategoryForTesting; | 36 static const char* const kTraceCategoryForTesting; |
41 | 37 |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
92 // This will never return kInvalidTracingProcessId. | 88 // This will never return kInvalidTracingProcessId. |
93 static uint64 ChildProcessIdToTracingProcessId(int child_id); | 89 static uint64 ChildProcessIdToTracingProcessId(int child_id); |
94 | 90 |
95 // Returns a unique id for the current process. The id can be retrieved only | 91 // Returns a unique id for the current process. The id can be retrieved only |
96 // by child processes and only when tracing is enabled. This is intended to | 92 // by child processes and only when tracing is enabled. This is intended to |
97 // express cross-process sharing of memory dumps on the child-process side, | 93 // express cross-process sharing of memory dumps on the child-process side, |
98 // without having to know its own child process id. | 94 // without having to know its own child process id. |
99 uint64 tracing_process_id() const { return tracing_process_id_; } | 95 uint64 tracing_process_id() const { return tracing_process_id_; } |
100 | 96 |
101 private: | 97 private: |
102 // Descriptor struct used to hold information about registered MDPs. It is | |
103 // deliberately copyable, in order to allow to be used as hash_map value. | |
104 struct MemoryDumpProviderInfo { | |
105 MemoryDumpProviderInfo( | |
106 const scoped_refptr<SingleThreadTaskRunner>& task_runner); | |
107 ~MemoryDumpProviderInfo(); | |
108 | |
109 scoped_refptr<SingleThreadTaskRunner> task_runner; // Optional. | |
110 int consecutive_failures; // Number of times the provider failed (to | |
111 // disable the MDPs). | |
112 bool disabled; // For fail-safe logic (auto-disable failing MDPs). | |
113 }; | |
114 | |
115 friend struct DefaultDeleter<MemoryDumpManager>; // For the testing instance. | 98 friend struct DefaultDeleter<MemoryDumpManager>; // For the testing instance. |
116 friend struct DefaultSingletonTraits<MemoryDumpManager>; | 99 friend struct DefaultSingletonTraits<MemoryDumpManager>; |
117 friend class MemoryDumpManagerDelegate; | 100 friend class MemoryDumpManagerDelegate; |
118 friend class MemoryDumpManagerTest; | 101 friend class MemoryDumpManagerTest; |
119 FRIEND_TEST_ALL_PREFIXES(MemoryDumpManagerTest, DisableFailingDumpers); | 102 FRIEND_TEST_ALL_PREFIXES(MemoryDumpManagerTest, DisableFailingDumpers); |
120 | 103 |
| 104 // Descriptor struct used to hold information about registered MDPs. It is |
| 105 // deliberately copyable, in order to allow it to be used as std::set value. |
| 106 struct MemoryDumpProviderInfo { |
| 107 MemoryDumpProviderInfo( |
| 108 MemoryDumpProvider* dump_provider, |
| 109 const scoped_refptr<SingleThreadTaskRunner>& task_runner); |
| 110 ~MemoryDumpProviderInfo(); |
| 111 |
| 112 // Define a total order based on the thread (i.e. |task_runner|) affinity, |
| 113 // so that all MDP belonging to the same thread are adjacent in the set. |
| 114 bool operator<(const MemoryDumpProviderInfo& other) const; |
| 115 |
| 116 MemoryDumpProvider* const dump_provider; |
| 117 scoped_refptr<SingleThreadTaskRunner> task_runner; // Optional. |
| 118 |
| 119 // For fail-safe logic (auto-disable failing MDPs). These fields are mutable |
| 120 // as can be safely changed without impacting the order within the set. |
| 121 mutable int consecutive_failures; |
| 122 mutable bool disabled; |
| 123 }; |
| 124 |
| 125 using MemoryDumpProviderInfoSet = std::set<MemoryDumpProviderInfo>; |
| 126 |
| 127 // Holds the state of a process memory dump that needs to be carried over |
| 128 // across threads in order to fulfil an asynchronous CreateProcessDump() |
| 129 // request. At any time exactly one thread owns a ProcessMemoryDumpAsyncState. |
| 130 struct ProcessMemoryDumpAsyncState { |
| 131 ProcessMemoryDumpAsyncState( |
| 132 MemoryDumpRequestArgs req_args, |
| 133 MemoryDumpProviderInfoSet::iterator next_dump_provider, |
| 134 const scoped_refptr<MemoryDumpSessionState>& session_state, |
| 135 MemoryDumpCallback callback); |
| 136 ~ProcessMemoryDumpAsyncState(); |
| 137 |
| 138 // The ProcessMemoryDump container, where each dump provider will dump its |
| 139 // own MemoryAllocatorDump(s) upon the OnMemoryDump() call. |
| 140 ProcessMemoryDump process_memory_dump; |
| 141 |
| 142 // The arguments passed to the initial CreateProcessDump() request. |
| 143 const MemoryDumpRequestArgs req_args; |
| 144 |
| 145 // The |dump_providers_| iterator to the next dump provider that should be |
| 146 // invoked (or dump_providers_.end() if at the end of the sequence). |
| 147 MemoryDumpProviderInfoSet::iterator next_dump_provider; |
| 148 |
| 149 // Callback passed to the initial call to CreateProcessDump(). |
| 150 MemoryDumpCallback callback; |
| 151 |
| 152 // The thread on which FinalizeDumpAndAddToTrace() (and hence |callback|) |
| 153 // should be invoked. This is the thread on which the initial |
| 154 // CreateProcessDump() request was called. |
| 155 const scoped_refptr<SingleThreadTaskRunner> task_runner; |
| 156 |
| 157 private: |
| 158 DISALLOW_COPY_AND_ASSIGN(ProcessMemoryDumpAsyncState); |
| 159 }; |
| 160 |
121 static const int kMaxConsecutiveFailuresCount; | 161 static const int kMaxConsecutiveFailuresCount; |
122 | 162 |
123 static void SetInstanceForTesting(MemoryDumpManager* instance); | |
124 | |
125 MemoryDumpManager(); | 163 MemoryDumpManager(); |
126 virtual ~MemoryDumpManager(); | 164 virtual ~MemoryDumpManager(); |
127 | 165 |
| 166 static void SetInstanceForTesting(MemoryDumpManager* instance); |
| 167 static void FinalizeDumpAndAddToTrace( |
| 168 scoped_ptr<ProcessMemoryDumpAsyncState> pmd_async_state); |
| 169 static void AbortDumpLocked(MemoryDumpCallback callback, |
| 170 scoped_refptr<SingleThreadTaskRunner> task_runner, |
| 171 uint64 dump_guid); |
| 172 |
128 // Internal, used only by MemoryDumpManagerDelegate. | 173 // Internal, used only by MemoryDumpManagerDelegate. |
129 // Creates a memory dump for the current process and appends it to the trace. | 174 // Creates a memory dump for the current process and appends it to the trace. |
130 // |callback| will be invoked asynchronously upon completion on the same | 175 // |callback| will be invoked asynchronously upon completion on the same |
131 // thread on which CreateProcessDump() was called. | 176 // thread on which CreateProcessDump() was called. |
132 void CreateProcessDump(const MemoryDumpRequestArgs& args, | 177 void CreateProcessDump(const MemoryDumpRequestArgs& args, |
133 const MemoryDumpCallback& callback); | 178 const MemoryDumpCallback& callback); |
134 | 179 |
135 bool InvokeDumpProviderLocked(MemoryDumpProvider* mdp, | 180 // Continues the ProcessMemoryDump started by CreateProcessDump(), hopping |
136 ProcessMemoryDump* pmd); | 181 // across threads as needed as specified by MDPs in RegisterDumpProvider(). |
137 void ContinueAsyncProcessDump( | 182 void ContinueAsyncProcessDump( |
138 MemoryDumpProvider* mdp, | 183 scoped_ptr<ProcessMemoryDumpAsyncState> pmd_async_state); |
139 scoped_refptr<ProcessMemoryDumpHolder> pmd_holder); | |
140 | 184 |
141 // Pass kInvalidTracingProcessId to invalidate the id. | 185 // Pass kInvalidTracingProcessId to invalidate the id. |
142 void set_tracing_process_id(uint64 id) { | 186 void set_tracing_process_id(uint64 id) { |
143 DCHECK(tracing_process_id_ == kInvalidTracingProcessId || | 187 DCHECK(tracing_process_id_ == kInvalidTracingProcessId || |
144 id == kInvalidTracingProcessId || tracing_process_id_ == id); | 188 id == kInvalidTracingProcessId || tracing_process_id_ == id); |
145 tracing_process_id_ = id; | 189 tracing_process_id_ = id; |
146 } | 190 } |
147 | 191 |
148 hash_map<MemoryDumpProvider*, MemoryDumpProviderInfo> dump_providers_; | 192 // An ordererd set of registered MemoryDumpProviderInfo(s), sorted by thread |
| 193 // affinity (MDPs belonging to the same thread are adjacent). |
| 194 MemoryDumpProviderInfoSet dump_providers_; |
| 195 |
| 196 // Flag used to signal that some provider was removed from |dump_providers_| |
| 197 // and therefore the current memory dump (if any) should be aborted. |
| 198 bool did_unregister_dump_provider_; |
149 | 199 |
150 // Shared among all the PMDs to keep state scoped to the tracing session. | 200 // Shared among all the PMDs to keep state scoped to the tracing session. |
151 scoped_refptr<MemoryDumpSessionState> session_state_; | 201 scoped_refptr<MemoryDumpSessionState> session_state_; |
152 | 202 |
153 MemoryDumpManagerDelegate* delegate_; // Not owned. | 203 MemoryDumpManagerDelegate* delegate_; // Not owned. |
154 | 204 |
155 // Protects from concurrent accesses to the |dump_providers_*| and |delegate_| | 205 // Protects from concurrent accesses to the |dump_providers_*| and |delegate_| |
156 // to guard against disabling logging while dumping on another thread. | 206 // to guard against disabling logging while dumping on another thread. |
157 Lock lock_; | 207 Lock lock_; |
158 | 208 |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
198 } | 248 } |
199 | 249 |
200 private: | 250 private: |
201 DISALLOW_COPY_AND_ASSIGN(MemoryDumpManagerDelegate); | 251 DISALLOW_COPY_AND_ASSIGN(MemoryDumpManagerDelegate); |
202 }; | 252 }; |
203 | 253 |
204 } // namespace trace_event | 254 } // namespace trace_event |
205 } // namespace base | 255 } // namespace base |
206 | 256 |
207 #endif // BASE_TRACE_EVENT_MEMORY_DUMP_MANAGER_H_ | 257 #endif // BASE_TRACE_EVENT_MEMORY_DUMP_MANAGER_H_ |
OLD | NEW |