xref: /aosp_15_r20/external/libchrome/base/debug/activity_tracker.h (revision 635a864187cb8b6c713ff48b7e790a6b21769273)
1*635a8641SAndroid Build Coastguard Worker // Copyright 2016 The Chromium Authors. All rights reserved.
2*635a8641SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*635a8641SAndroid Build Coastguard Worker // found in the LICENSE file.
4*635a8641SAndroid Build Coastguard Worker 
5*635a8641SAndroid Build Coastguard Worker // Activity tracking provides a low-overhead method of collecting information
6*635a8641SAndroid Build Coastguard Worker // about the state of the application for analysis both while it is running
7*635a8641SAndroid Build Coastguard Worker // and after it has terminated unexpectedly. Its primary purpose is to help
8*635a8641SAndroid Build Coastguard Worker // locate reasons the browser becomes unresponsive by providing insight into
9*635a8641SAndroid Build Coastguard Worker // what all the various threads and processes are (or were) doing.
10*635a8641SAndroid Build Coastguard Worker 
11*635a8641SAndroid Build Coastguard Worker #ifndef BASE_DEBUG_ACTIVITY_TRACKER_H_
12*635a8641SAndroid Build Coastguard Worker #define BASE_DEBUG_ACTIVITY_TRACKER_H_
13*635a8641SAndroid Build Coastguard Worker 
14*635a8641SAndroid Build Coastguard Worker // std::atomic is undesired due to performance issues when used as global
15*635a8641SAndroid Build Coastguard Worker // variables. There are no such instances here. This module uses the
16*635a8641SAndroid Build Coastguard Worker // PersistentMemoryAllocator which also uses std::atomic and is written
17*635a8641SAndroid Build Coastguard Worker // by the same author.
18*635a8641SAndroid Build Coastguard Worker #include <atomic>
19*635a8641SAndroid Build Coastguard Worker #include <map>
20*635a8641SAndroid Build Coastguard Worker #include <memory>
21*635a8641SAndroid Build Coastguard Worker #include <string>
22*635a8641SAndroid Build Coastguard Worker #include <vector>
23*635a8641SAndroid Build Coastguard Worker 
24*635a8641SAndroid Build Coastguard Worker #include "base/atomicops.h"
25*635a8641SAndroid Build Coastguard Worker #include "base/base_export.h"
26*635a8641SAndroid Build Coastguard Worker #include "base/callback.h"
27*635a8641SAndroid Build Coastguard Worker #include "base/compiler_specific.h"
28*635a8641SAndroid Build Coastguard Worker #include "base/gtest_prod_util.h"
29*635a8641SAndroid Build Coastguard Worker #include "base/location.h"
30*635a8641SAndroid Build Coastguard Worker #include "base/memory/shared_memory.h"
31*635a8641SAndroid Build Coastguard Worker #include "base/metrics/persistent_memory_allocator.h"
32*635a8641SAndroid Build Coastguard Worker #include "base/process/process_handle.h"
33*635a8641SAndroid Build Coastguard Worker #include "base/strings/string_piece.h"
34*635a8641SAndroid Build Coastguard Worker #include "base/strings/utf_string_conversions.h"
35*635a8641SAndroid Build Coastguard Worker #include "base/task_runner.h"
36*635a8641SAndroid Build Coastguard Worker #include "base/threading/platform_thread.h"
37*635a8641SAndroid Build Coastguard Worker #include "base/threading/thread_local_storage.h"
38*635a8641SAndroid Build Coastguard Worker 
39*635a8641SAndroid Build Coastguard Worker namespace base {
40*635a8641SAndroid Build Coastguard Worker 
41*635a8641SAndroid Build Coastguard Worker struct PendingTask;
42*635a8641SAndroid Build Coastguard Worker 
43*635a8641SAndroid Build Coastguard Worker class FilePath;
44*635a8641SAndroid Build Coastguard Worker class Lock;
45*635a8641SAndroid Build Coastguard Worker class PlatformThreadHandle;
46*635a8641SAndroid Build Coastguard Worker class Process;
47*635a8641SAndroid Build Coastguard Worker class WaitableEvent;
48*635a8641SAndroid Build Coastguard Worker 
49*635a8641SAndroid Build Coastguard Worker namespace debug {
50*635a8641SAndroid Build Coastguard Worker 
51*635a8641SAndroid Build Coastguard Worker class ThreadActivityTracker;
52*635a8641SAndroid Build Coastguard Worker 
53*635a8641SAndroid Build Coastguard Worker 
54*635a8641SAndroid Build Coastguard Worker enum : int {
55*635a8641SAndroid Build Coastguard Worker   // The maximum number of call-stack addresses stored per activity. This
56*635a8641SAndroid Build Coastguard Worker   // cannot be changed without also changing the version number of the
57*635a8641SAndroid Build Coastguard Worker   // structure. See kTypeIdActivityTracker in GlobalActivityTracker.
58*635a8641SAndroid Build Coastguard Worker   kActivityCallStackSize = 10,
59*635a8641SAndroid Build Coastguard Worker };
60*635a8641SAndroid Build Coastguard Worker 
61*635a8641SAndroid Build Coastguard Worker // A class for keeping all information needed to verify that a structure is
62*635a8641SAndroid Build Coastguard Worker // associated with a given process.
63*635a8641SAndroid Build Coastguard Worker struct OwningProcess {
64*635a8641SAndroid Build Coastguard Worker   OwningProcess();
65*635a8641SAndroid Build Coastguard Worker   ~OwningProcess();
66*635a8641SAndroid Build Coastguard Worker 
67*635a8641SAndroid Build Coastguard Worker   // Initializes structure with the current process id and the current time.
68*635a8641SAndroid Build Coastguard Worker   // These can uniquely identify a process. A unique non-zero data_id will be
69*635a8641SAndroid Build Coastguard Worker   // set making it possible to tell using atomic reads if the data has changed.
70*635a8641SAndroid Build Coastguard Worker   void Release_Initialize(int64_t pid = 0);
71*635a8641SAndroid Build Coastguard Worker 
72*635a8641SAndroid Build Coastguard Worker   // Explicitly sets the process ID.
73*635a8641SAndroid Build Coastguard Worker   void SetOwningProcessIdForTesting(int64_t pid, int64_t stamp);
74*635a8641SAndroid Build Coastguard Worker 
75*635a8641SAndroid Build Coastguard Worker   // Gets the associated process ID, in native form, and the creation timestamp
76*635a8641SAndroid Build Coastguard Worker   // from memory without loading the entire structure for analysis. This will
77*635a8641SAndroid Build Coastguard Worker   // return false if no valid process ID is available.
78*635a8641SAndroid Build Coastguard Worker   static bool GetOwningProcessId(const void* memory,
79*635a8641SAndroid Build Coastguard Worker                                  int64_t* out_id,
80*635a8641SAndroid Build Coastguard Worker                                  int64_t* out_stamp);
81*635a8641SAndroid Build Coastguard Worker 
82*635a8641SAndroid Build Coastguard Worker   // SHA1(base::debug::OwningProcess): Increment this if structure changes!
83*635a8641SAndroid Build Coastguard Worker   static constexpr uint32_t kPersistentTypeId = 0xB1179672 + 1;
84*635a8641SAndroid Build Coastguard Worker 
85*635a8641SAndroid Build Coastguard Worker   // Expected size for 32/64-bit check by PersistentMemoryAllocator.
86*635a8641SAndroid Build Coastguard Worker   static constexpr size_t kExpectedInstanceSize = 24;
87*635a8641SAndroid Build Coastguard Worker 
88*635a8641SAndroid Build Coastguard Worker   std::atomic<uint32_t> data_id;
89*635a8641SAndroid Build Coastguard Worker   uint32_t padding;
90*635a8641SAndroid Build Coastguard Worker   int64_t process_id;
91*635a8641SAndroid Build Coastguard Worker   int64_t create_stamp;
92*635a8641SAndroid Build Coastguard Worker };
93*635a8641SAndroid Build Coastguard Worker 
94*635a8641SAndroid Build Coastguard Worker // The data associated with an activity is dependent upon the activity type.
95*635a8641SAndroid Build Coastguard Worker // This union defines all of the various fields. All fields must be explicitly
96*635a8641SAndroid Build Coastguard Worker // sized types to ensure no interoperability problems between 32-bit and
97*635a8641SAndroid Build Coastguard Worker // 64-bit systems.
98*635a8641SAndroid Build Coastguard Worker union ActivityData {
99*635a8641SAndroid Build Coastguard Worker   // Expected size for 32/64-bit check.
100*635a8641SAndroid Build Coastguard Worker   // TODO(bcwhite): VC2015 doesn't allow statics in unions. Fix when it does.
101*635a8641SAndroid Build Coastguard Worker   // static constexpr size_t kExpectedInstanceSize = 8;
102*635a8641SAndroid Build Coastguard Worker 
103*635a8641SAndroid Build Coastguard Worker   // Generic activities don't have any defined structure.
104*635a8641SAndroid Build Coastguard Worker   struct {
105*635a8641SAndroid Build Coastguard Worker     uint32_t id;   // An arbitrary identifier used for association.
106*635a8641SAndroid Build Coastguard Worker     int32_t info;  // An arbitrary value used for information purposes.
107*635a8641SAndroid Build Coastguard Worker   } generic;
108*635a8641SAndroid Build Coastguard Worker   struct {
109*635a8641SAndroid Build Coastguard Worker     uint64_t sequence_id;  // The sequence identifier of the posted task.
110*635a8641SAndroid Build Coastguard Worker   } task;
111*635a8641SAndroid Build Coastguard Worker   struct {
112*635a8641SAndroid Build Coastguard Worker     uint64_t lock_address;  // The memory address of the lock object.
113*635a8641SAndroid Build Coastguard Worker   } lock;
114*635a8641SAndroid Build Coastguard Worker   struct {
115*635a8641SAndroid Build Coastguard Worker     uint64_t event_address;  // The memory address of the event object.
116*635a8641SAndroid Build Coastguard Worker   } event;
117*635a8641SAndroid Build Coastguard Worker   struct {
118*635a8641SAndroid Build Coastguard Worker     int64_t thread_id;  // A unique identifier for a thread within a process.
119*635a8641SAndroid Build Coastguard Worker   } thread;
120*635a8641SAndroid Build Coastguard Worker   struct {
121*635a8641SAndroid Build Coastguard Worker     int64_t process_id;  // A unique identifier for a process.
122*635a8641SAndroid Build Coastguard Worker   } process;
123*635a8641SAndroid Build Coastguard Worker   struct {
124*635a8641SAndroid Build Coastguard Worker     uint32_t code;  // An "exception code" number.
125*635a8641SAndroid Build Coastguard Worker   } exception;
126*635a8641SAndroid Build Coastguard Worker 
127*635a8641SAndroid Build Coastguard Worker   // These methods create an ActivityData object from the appropriate
128*635a8641SAndroid Build Coastguard Worker   // parameters. Objects of this type should always be created this way to
129*635a8641SAndroid Build Coastguard Worker   // ensure that no fields remain unpopulated should the set of recorded
130*635a8641SAndroid Build Coastguard Worker   // fields change. They're defined inline where practical because they
131*635a8641SAndroid Build Coastguard Worker   // reduce to loading a small local structure with a few values, roughly
132*635a8641SAndroid Build Coastguard Worker   // the same as loading all those values into parameters.
133*635a8641SAndroid Build Coastguard Worker 
ForGeneric(uint32_t id,int32_t info)134*635a8641SAndroid Build Coastguard Worker   static ActivityData ForGeneric(uint32_t id, int32_t info) {
135*635a8641SAndroid Build Coastguard Worker     ActivityData data;
136*635a8641SAndroid Build Coastguard Worker     data.generic.id = id;
137*635a8641SAndroid Build Coastguard Worker     data.generic.info = info;
138*635a8641SAndroid Build Coastguard Worker     return data;
139*635a8641SAndroid Build Coastguard Worker   }
140*635a8641SAndroid Build Coastguard Worker 
ForTask(uint64_t sequence)141*635a8641SAndroid Build Coastguard Worker   static ActivityData ForTask(uint64_t sequence) {
142*635a8641SAndroid Build Coastguard Worker     ActivityData data;
143*635a8641SAndroid Build Coastguard Worker     data.task.sequence_id = sequence;
144*635a8641SAndroid Build Coastguard Worker     return data;
145*635a8641SAndroid Build Coastguard Worker   }
146*635a8641SAndroid Build Coastguard Worker 
ForLock(const void * lock)147*635a8641SAndroid Build Coastguard Worker   static ActivityData ForLock(const void* lock) {
148*635a8641SAndroid Build Coastguard Worker     ActivityData data;
149*635a8641SAndroid Build Coastguard Worker     data.lock.lock_address = reinterpret_cast<uintptr_t>(lock);
150*635a8641SAndroid Build Coastguard Worker     return data;
151*635a8641SAndroid Build Coastguard Worker   }
152*635a8641SAndroid Build Coastguard Worker 
ForEvent(const void * event)153*635a8641SAndroid Build Coastguard Worker   static ActivityData ForEvent(const void* event) {
154*635a8641SAndroid Build Coastguard Worker     ActivityData data;
155*635a8641SAndroid Build Coastguard Worker     data.event.event_address = reinterpret_cast<uintptr_t>(event);
156*635a8641SAndroid Build Coastguard Worker     return data;
157*635a8641SAndroid Build Coastguard Worker   }
158*635a8641SAndroid Build Coastguard Worker 
159*635a8641SAndroid Build Coastguard Worker   static ActivityData ForThread(const PlatformThreadHandle& handle);
ForThread(const int64_t id)160*635a8641SAndroid Build Coastguard Worker   static ActivityData ForThread(const int64_t id) {
161*635a8641SAndroid Build Coastguard Worker     ActivityData data;
162*635a8641SAndroid Build Coastguard Worker     data.thread.thread_id = id;
163*635a8641SAndroid Build Coastguard Worker     return data;
164*635a8641SAndroid Build Coastguard Worker   }
165*635a8641SAndroid Build Coastguard Worker 
ForProcess(const int64_t id)166*635a8641SAndroid Build Coastguard Worker   static ActivityData ForProcess(const int64_t id) {
167*635a8641SAndroid Build Coastguard Worker     ActivityData data;
168*635a8641SAndroid Build Coastguard Worker     data.process.process_id = id;
169*635a8641SAndroid Build Coastguard Worker     return data;
170*635a8641SAndroid Build Coastguard Worker   }
171*635a8641SAndroid Build Coastguard Worker 
ForException(const uint32_t code)172*635a8641SAndroid Build Coastguard Worker   static ActivityData ForException(const uint32_t code) {
173*635a8641SAndroid Build Coastguard Worker     ActivityData data;
174*635a8641SAndroid Build Coastguard Worker     data.exception.code = code;
175*635a8641SAndroid Build Coastguard Worker     return data;
176*635a8641SAndroid Build Coastguard Worker   }
177*635a8641SAndroid Build Coastguard Worker };
178*635a8641SAndroid Build Coastguard Worker 
179*635a8641SAndroid Build Coastguard Worker // A "null" activity-data that can be passed to indicate "do not change".
180*635a8641SAndroid Build Coastguard Worker extern const ActivityData kNullActivityData;
181*635a8641SAndroid Build Coastguard Worker 
182*635a8641SAndroid Build Coastguard Worker 
183*635a8641SAndroid Build Coastguard Worker // A helper class that is used for managing memory allocations within a
184*635a8641SAndroid Build Coastguard Worker // persistent memory allocator. Instances of this class are NOT thread-safe.
185*635a8641SAndroid Build Coastguard Worker // Use from a single thread or protect access with a lock.
186*635a8641SAndroid Build Coastguard Worker class BASE_EXPORT ActivityTrackerMemoryAllocator {
187*635a8641SAndroid Build Coastguard Worker  public:
188*635a8641SAndroid Build Coastguard Worker   using Reference = PersistentMemoryAllocator::Reference;
189*635a8641SAndroid Build Coastguard Worker 
190*635a8641SAndroid Build Coastguard Worker   // Creates a instance for allocating objects of a fixed |object_type|, a
191*635a8641SAndroid Build Coastguard Worker   // corresponding |object_free| type, and the |object_size|. An internal
192*635a8641SAndroid Build Coastguard Worker   // cache of the last |cache_size| released references will be kept for
193*635a8641SAndroid Build Coastguard Worker   // quick future fetches. If |make_iterable| then allocated objects will
194*635a8641SAndroid Build Coastguard Worker   // be marked "iterable" in the allocator.
195*635a8641SAndroid Build Coastguard Worker   ActivityTrackerMemoryAllocator(PersistentMemoryAllocator* allocator,
196*635a8641SAndroid Build Coastguard Worker                                  uint32_t object_type,
197*635a8641SAndroid Build Coastguard Worker                                  uint32_t object_free_type,
198*635a8641SAndroid Build Coastguard Worker                                  size_t object_size,
199*635a8641SAndroid Build Coastguard Worker                                  size_t cache_size,
200*635a8641SAndroid Build Coastguard Worker                                  bool make_iterable);
201*635a8641SAndroid Build Coastguard Worker   ~ActivityTrackerMemoryAllocator();
202*635a8641SAndroid Build Coastguard Worker 
203*635a8641SAndroid Build Coastguard Worker   // Gets a reference to an object of the configured type. This can return
204*635a8641SAndroid Build Coastguard Worker   // a null reference if it was not possible to allocate the memory.
205*635a8641SAndroid Build Coastguard Worker   Reference GetObjectReference();
206*635a8641SAndroid Build Coastguard Worker 
207*635a8641SAndroid Build Coastguard Worker   // Returns an object to the "free" pool.
208*635a8641SAndroid Build Coastguard Worker   void ReleaseObjectReference(Reference ref);
209*635a8641SAndroid Build Coastguard Worker 
210*635a8641SAndroid Build Coastguard Worker   // Helper function to access an object allocated using this instance.
211*635a8641SAndroid Build Coastguard Worker   template <typename T>
GetAsObject(Reference ref)212*635a8641SAndroid Build Coastguard Worker   T* GetAsObject(Reference ref) {
213*635a8641SAndroid Build Coastguard Worker     return allocator_->GetAsObject<T>(ref);
214*635a8641SAndroid Build Coastguard Worker   }
215*635a8641SAndroid Build Coastguard Worker 
216*635a8641SAndroid Build Coastguard Worker   // Similar to GetAsObject() but converts references to arrays of objects.
217*635a8641SAndroid Build Coastguard Worker   template <typename T>
GetAsArray(Reference ref,size_t count)218*635a8641SAndroid Build Coastguard Worker   T* GetAsArray(Reference ref, size_t count) {
219*635a8641SAndroid Build Coastguard Worker     return allocator_->GetAsArray<T>(ref, object_type_, count);
220*635a8641SAndroid Build Coastguard Worker   }
221*635a8641SAndroid Build Coastguard Worker 
222*635a8641SAndroid Build Coastguard Worker   // The current "used size" of the internal cache, visible for testing.
cache_used()223*635a8641SAndroid Build Coastguard Worker   size_t cache_used() const { return cache_used_; }
224*635a8641SAndroid Build Coastguard Worker 
225*635a8641SAndroid Build Coastguard Worker  private:
226*635a8641SAndroid Build Coastguard Worker   PersistentMemoryAllocator* const allocator_;
227*635a8641SAndroid Build Coastguard Worker   const uint32_t object_type_;
228*635a8641SAndroid Build Coastguard Worker   const uint32_t object_free_type_;
229*635a8641SAndroid Build Coastguard Worker   const size_t object_size_;
230*635a8641SAndroid Build Coastguard Worker   const size_t cache_size_;
231*635a8641SAndroid Build Coastguard Worker   const bool make_iterable_;
232*635a8641SAndroid Build Coastguard Worker 
233*635a8641SAndroid Build Coastguard Worker   // An iterator for going through persistent memory looking for free'd objects.
234*635a8641SAndroid Build Coastguard Worker   PersistentMemoryAllocator::Iterator iterator_;
235*635a8641SAndroid Build Coastguard Worker 
236*635a8641SAndroid Build Coastguard Worker   // The cache of released object memories.
237*635a8641SAndroid Build Coastguard Worker   std::unique_ptr<Reference[]> cache_values_;
238*635a8641SAndroid Build Coastguard Worker   size_t cache_used_;
239*635a8641SAndroid Build Coastguard Worker 
240*635a8641SAndroid Build Coastguard Worker   DISALLOW_COPY_AND_ASSIGN(ActivityTrackerMemoryAllocator);
241*635a8641SAndroid Build Coastguard Worker };
242*635a8641SAndroid Build Coastguard Worker 
243*635a8641SAndroid Build Coastguard Worker 
244*635a8641SAndroid Build Coastguard Worker // This structure is the full contents recorded for every activity pushed
245*635a8641SAndroid Build Coastguard Worker // onto the stack. The |activity_type| indicates what is actually stored in
246*635a8641SAndroid Build Coastguard Worker // the |data| field. All fields must be explicitly sized types to ensure no
247*635a8641SAndroid Build Coastguard Worker // interoperability problems between 32-bit and 64-bit systems.
248*635a8641SAndroid Build Coastguard Worker struct Activity {
249*635a8641SAndroid Build Coastguard Worker   // SHA1(base::debug::Activity): Increment this if structure changes!
250*635a8641SAndroid Build Coastguard Worker   static constexpr uint32_t kPersistentTypeId = 0x99425159 + 1;
251*635a8641SAndroid Build Coastguard Worker   // Expected size for 32/64-bit check. Update this if structure changes!
252*635a8641SAndroid Build Coastguard Worker   static constexpr size_t kExpectedInstanceSize =
253*635a8641SAndroid Build Coastguard Worker       48 + 8 * kActivityCallStackSize;
254*635a8641SAndroid Build Coastguard Worker 
255*635a8641SAndroid Build Coastguard Worker   // The type of an activity on the stack. Activities are broken into
256*635a8641SAndroid Build Coastguard Worker   // categories with the category ID taking the top 4 bits and the lower
257*635a8641SAndroid Build Coastguard Worker   // bits representing an action within that category. This combination
258*635a8641SAndroid Build Coastguard Worker   // makes it easy to "switch" based on the type during analysis.
259*635a8641SAndroid Build Coastguard Worker   enum Type : uint8_t {
260*635a8641SAndroid Build Coastguard Worker     // This "null" constant is used to indicate "do not change" in calls.
261*635a8641SAndroid Build Coastguard Worker     ACT_NULL = 0,
262*635a8641SAndroid Build Coastguard Worker 
263*635a8641SAndroid Build Coastguard Worker     // Task activities involve callbacks posted to a thread or thread-pool
264*635a8641SAndroid Build Coastguard Worker     // using the PostTask() method or any of its friends.
265*635a8641SAndroid Build Coastguard Worker     ACT_TASK = 1 << 4,
266*635a8641SAndroid Build Coastguard Worker     ACT_TASK_RUN = ACT_TASK,
267*635a8641SAndroid Build Coastguard Worker 
268*635a8641SAndroid Build Coastguard Worker     // Lock activities involve the acquisition of "mutex" locks.
269*635a8641SAndroid Build Coastguard Worker     ACT_LOCK = 2 << 4,
270*635a8641SAndroid Build Coastguard Worker     ACT_LOCK_ACQUIRE = ACT_LOCK,
271*635a8641SAndroid Build Coastguard Worker     ACT_LOCK_RELEASE,
272*635a8641SAndroid Build Coastguard Worker 
273*635a8641SAndroid Build Coastguard Worker     // Event activities involve operations on a WaitableEvent.
274*635a8641SAndroid Build Coastguard Worker     ACT_EVENT = 3 << 4,
275*635a8641SAndroid Build Coastguard Worker     ACT_EVENT_WAIT = ACT_EVENT,
276*635a8641SAndroid Build Coastguard Worker     ACT_EVENT_SIGNAL,
277*635a8641SAndroid Build Coastguard Worker 
278*635a8641SAndroid Build Coastguard Worker     // Thread activities involve the life management of threads.
279*635a8641SAndroid Build Coastguard Worker     ACT_THREAD = 4 << 4,
280*635a8641SAndroid Build Coastguard Worker     ACT_THREAD_START = ACT_THREAD,
281*635a8641SAndroid Build Coastguard Worker     ACT_THREAD_JOIN,
282*635a8641SAndroid Build Coastguard Worker 
283*635a8641SAndroid Build Coastguard Worker     // Process activities involve the life management of processes.
284*635a8641SAndroid Build Coastguard Worker     ACT_PROCESS = 5 << 4,
285*635a8641SAndroid Build Coastguard Worker     ACT_PROCESS_START = ACT_PROCESS,
286*635a8641SAndroid Build Coastguard Worker     ACT_PROCESS_WAIT,
287*635a8641SAndroid Build Coastguard Worker 
288*635a8641SAndroid Build Coastguard Worker     // Exception activities indicate the occurence of something unexpected.
289*635a8641SAndroid Build Coastguard Worker     ACT_EXCEPTION = 14 << 4,
290*635a8641SAndroid Build Coastguard Worker 
291*635a8641SAndroid Build Coastguard Worker     // Generic activities are user defined and can be anything.
292*635a8641SAndroid Build Coastguard Worker     ACT_GENERIC = 15 << 4,
293*635a8641SAndroid Build Coastguard Worker 
294*635a8641SAndroid Build Coastguard Worker     // These constants can be used to separate the category and action from
295*635a8641SAndroid Build Coastguard Worker     // a combined activity type.
296*635a8641SAndroid Build Coastguard Worker     ACT_CATEGORY_MASK = 0xF << 4,
297*635a8641SAndroid Build Coastguard Worker     ACT_ACTION_MASK = 0xF
298*635a8641SAndroid Build Coastguard Worker   };
299*635a8641SAndroid Build Coastguard Worker 
300*635a8641SAndroid Build Coastguard Worker   // Internal representation of time. During collection, this is in "ticks"
301*635a8641SAndroid Build Coastguard Worker   // but when returned in a snapshot, it is "wall time".
302*635a8641SAndroid Build Coastguard Worker   int64_t time_internal;
303*635a8641SAndroid Build Coastguard Worker 
304*635a8641SAndroid Build Coastguard Worker   // The address that pushed the activity onto the stack as a raw number.
305*635a8641SAndroid Build Coastguard Worker   uint64_t calling_address;
306*635a8641SAndroid Build Coastguard Worker 
307*635a8641SAndroid Build Coastguard Worker   // The address that is the origin of the activity if it not obvious from
308*635a8641SAndroid Build Coastguard Worker   // the call stack. This is useful for things like tasks that are posted
309*635a8641SAndroid Build Coastguard Worker   // from a completely different thread though most activities will leave
310*635a8641SAndroid Build Coastguard Worker   // it null.
311*635a8641SAndroid Build Coastguard Worker   uint64_t origin_address;
312*635a8641SAndroid Build Coastguard Worker 
313*635a8641SAndroid Build Coastguard Worker   // Array of program-counters that make up the top of the call stack.
314*635a8641SAndroid Build Coastguard Worker   // Despite the fixed size, this list is always null-terminated. Entries
315*635a8641SAndroid Build Coastguard Worker   // after the terminator have no meaning and may or may not also be null.
316*635a8641SAndroid Build Coastguard Worker   // The list will be completely empty if call-stack collection is not
317*635a8641SAndroid Build Coastguard Worker   // enabled.
318*635a8641SAndroid Build Coastguard Worker   uint64_t call_stack[kActivityCallStackSize];
319*635a8641SAndroid Build Coastguard Worker 
320*635a8641SAndroid Build Coastguard Worker   // Reference to arbitrary user data within the persistent memory segment
321*635a8641SAndroid Build Coastguard Worker   // and a unique identifier for it.
322*635a8641SAndroid Build Coastguard Worker   uint32_t user_data_ref;
323*635a8641SAndroid Build Coastguard Worker   uint32_t user_data_id;
324*635a8641SAndroid Build Coastguard Worker 
325*635a8641SAndroid Build Coastguard Worker   // The (enumerated) type of the activity. This defines what fields of the
326*635a8641SAndroid Build Coastguard Worker   // |data| record are valid.
327*635a8641SAndroid Build Coastguard Worker   uint8_t activity_type;
328*635a8641SAndroid Build Coastguard Worker 
329*635a8641SAndroid Build Coastguard Worker   // Padding to ensure that the next member begins on a 64-bit boundary
330*635a8641SAndroid Build Coastguard Worker   // even on 32-bit builds which ensures inter-operability between CPU
331*635a8641SAndroid Build Coastguard Worker   // architectures. New fields can be taken from this space.
332*635a8641SAndroid Build Coastguard Worker   uint8_t padding[7];
333*635a8641SAndroid Build Coastguard Worker 
334*635a8641SAndroid Build Coastguard Worker   // Information specific to the |activity_type|.
335*635a8641SAndroid Build Coastguard Worker   ActivityData data;
336*635a8641SAndroid Build Coastguard Worker 
337*635a8641SAndroid Build Coastguard Worker   static void FillFrom(Activity* activity,
338*635a8641SAndroid Build Coastguard Worker                        const void* program_counter,
339*635a8641SAndroid Build Coastguard Worker                        const void* origin,
340*635a8641SAndroid Build Coastguard Worker                        Type type,
341*635a8641SAndroid Build Coastguard Worker                        const ActivityData& data);
342*635a8641SAndroid Build Coastguard Worker };
343*635a8641SAndroid Build Coastguard Worker 
344*635a8641SAndroid Build Coastguard Worker // This class manages arbitrary user data that can be associated with activities
345*635a8641SAndroid Build Coastguard Worker // done by a thread by supporting key/value pairs of any type. This can provide
346*635a8641SAndroid Build Coastguard Worker // additional information during debugging. It is also used to store arbitrary
347*635a8641SAndroid Build Coastguard Worker // global data. All updates must be done from the same thread though other
348*635a8641SAndroid Build Coastguard Worker // threads can read it concurrently if they create new objects using the same
349*635a8641SAndroid Build Coastguard Worker // memory.
350*635a8641SAndroid Build Coastguard Worker class BASE_EXPORT ActivityUserData {
351*635a8641SAndroid Build Coastguard Worker  public:
352*635a8641SAndroid Build Coastguard Worker   // List of known value type. REFERENCE types must immediately follow the non-
353*635a8641SAndroid Build Coastguard Worker   // external types.
354*635a8641SAndroid Build Coastguard Worker   enum ValueType : uint8_t {
355*635a8641SAndroid Build Coastguard Worker     END_OF_VALUES = 0,
356*635a8641SAndroid Build Coastguard Worker     RAW_VALUE,
357*635a8641SAndroid Build Coastguard Worker     RAW_VALUE_REFERENCE,
358*635a8641SAndroid Build Coastguard Worker     STRING_VALUE,
359*635a8641SAndroid Build Coastguard Worker     STRING_VALUE_REFERENCE,
360*635a8641SAndroid Build Coastguard Worker     CHAR_VALUE,
361*635a8641SAndroid Build Coastguard Worker     BOOL_VALUE,
362*635a8641SAndroid Build Coastguard Worker     SIGNED_VALUE,
363*635a8641SAndroid Build Coastguard Worker     UNSIGNED_VALUE,
364*635a8641SAndroid Build Coastguard Worker   };
365*635a8641SAndroid Build Coastguard Worker 
366*635a8641SAndroid Build Coastguard Worker   class BASE_EXPORT TypedValue {
367*635a8641SAndroid Build Coastguard Worker    public:
368*635a8641SAndroid Build Coastguard Worker     TypedValue();
369*635a8641SAndroid Build Coastguard Worker     TypedValue(const TypedValue& other);
370*635a8641SAndroid Build Coastguard Worker     ~TypedValue();
371*635a8641SAndroid Build Coastguard Worker 
type()372*635a8641SAndroid Build Coastguard Worker     ValueType type() const { return type_; }
373*635a8641SAndroid Build Coastguard Worker 
374*635a8641SAndroid Build Coastguard Worker     // These methods return the extracted value in the correct format.
375*635a8641SAndroid Build Coastguard Worker     StringPiece Get() const;
376*635a8641SAndroid Build Coastguard Worker     StringPiece GetString() const;
377*635a8641SAndroid Build Coastguard Worker     bool GetBool() const;
378*635a8641SAndroid Build Coastguard Worker     char GetChar() const;
379*635a8641SAndroid Build Coastguard Worker     int64_t GetInt() const;
380*635a8641SAndroid Build Coastguard Worker     uint64_t GetUint() const;
381*635a8641SAndroid Build Coastguard Worker 
382*635a8641SAndroid Build Coastguard Worker     // These methods return references to process memory as originally provided
383*635a8641SAndroid Build Coastguard Worker     // to corresponding Set calls. USE WITH CAUTION! There is no guarantee that
384*635a8641SAndroid Build Coastguard Worker     // the referenced memory is assessible or useful.  It's possible that:
385*635a8641SAndroid Build Coastguard Worker     //  - the memory was free'd and reallocated for a different purpose
386*635a8641SAndroid Build Coastguard Worker     //  - the memory has been released back to the OS
387*635a8641SAndroid Build Coastguard Worker     //  - the memory belongs to a different process's address space
388*635a8641SAndroid Build Coastguard Worker     // Dereferencing the returned StringPiece when the memory is not accessible
389*635a8641SAndroid Build Coastguard Worker     // will cause the program to SEGV!
390*635a8641SAndroid Build Coastguard Worker     StringPiece GetReference() const;
391*635a8641SAndroid Build Coastguard Worker     StringPiece GetStringReference() const;
392*635a8641SAndroid Build Coastguard Worker 
393*635a8641SAndroid Build Coastguard Worker    private:
394*635a8641SAndroid Build Coastguard Worker     friend class ActivityUserData;
395*635a8641SAndroid Build Coastguard Worker 
396*635a8641SAndroid Build Coastguard Worker     ValueType type_ = END_OF_VALUES;
397*635a8641SAndroid Build Coastguard Worker     uint64_t short_value_;    // Used to hold copy of numbers, etc.
398*635a8641SAndroid Build Coastguard Worker     std::string long_value_;  // Used to hold copy of raw/string data.
399*635a8641SAndroid Build Coastguard Worker     StringPiece ref_value_;   // Used to hold reference to external data.
400*635a8641SAndroid Build Coastguard Worker   };
401*635a8641SAndroid Build Coastguard Worker 
402*635a8641SAndroid Build Coastguard Worker   using Snapshot = std::map<std::string, TypedValue>;
403*635a8641SAndroid Build Coastguard Worker 
404*635a8641SAndroid Build Coastguard Worker   // Initialize the object either as a "sink" that just accepts and discards
405*635a8641SAndroid Build Coastguard Worker   // data or an active one that writes to a given (zeroed) memory block.
406*635a8641SAndroid Build Coastguard Worker   ActivityUserData();
407*635a8641SAndroid Build Coastguard Worker   ActivityUserData(void* memory, size_t size, int64_t pid = 0);
408*635a8641SAndroid Build Coastguard Worker   virtual ~ActivityUserData();
409*635a8641SAndroid Build Coastguard Worker 
410*635a8641SAndroid Build Coastguard Worker   // Gets the unique ID number for this user data. If this changes then the
411*635a8641SAndroid Build Coastguard Worker   // contents have been overwritten by another thread. The return value is
412*635a8641SAndroid Build Coastguard Worker   // always non-zero unless it's actually just a data "sink".
id()413*635a8641SAndroid Build Coastguard Worker   uint32_t id() const {
414*635a8641SAndroid Build Coastguard Worker     return header_ ? header_->owner.data_id.load(std::memory_order_relaxed) : 0;
415*635a8641SAndroid Build Coastguard Worker   }
416*635a8641SAndroid Build Coastguard Worker 
417*635a8641SAndroid Build Coastguard Worker   // Writes a |value| (as part of a key/value pair) that will be included with
418*635a8641SAndroid Build Coastguard Worker   // the activity in any reports. The same |name| can be written multiple times
419*635a8641SAndroid Build Coastguard Worker   // with each successive call overwriting the previously stored |value|. For
420*635a8641SAndroid Build Coastguard Worker   // raw and string values, the maximum size of successive writes is limited by
421*635a8641SAndroid Build Coastguard Worker   // the first call. The length of "name" is limited to 255 characters.
422*635a8641SAndroid Build Coastguard Worker   //
423*635a8641SAndroid Build Coastguard Worker   // This information is stored on a "best effort" basis. It may be dropped if
424*635a8641SAndroid Build Coastguard Worker   // the memory buffer is full or the associated activity is beyond the maximum
425*635a8641SAndroid Build Coastguard Worker   // recording depth.
Set(StringPiece name,const void * memory,size_t size)426*635a8641SAndroid Build Coastguard Worker   void Set(StringPiece name, const void* memory, size_t size) {
427*635a8641SAndroid Build Coastguard Worker     Set(name, RAW_VALUE, memory, size);
428*635a8641SAndroid Build Coastguard Worker   }
SetString(StringPiece name,StringPiece value)429*635a8641SAndroid Build Coastguard Worker   void SetString(StringPiece name, StringPiece value) {
430*635a8641SAndroid Build Coastguard Worker     Set(name, STRING_VALUE, value.data(), value.length());
431*635a8641SAndroid Build Coastguard Worker   }
SetString(StringPiece name,StringPiece16 value)432*635a8641SAndroid Build Coastguard Worker   void SetString(StringPiece name, StringPiece16 value) {
433*635a8641SAndroid Build Coastguard Worker     SetString(name, UTF16ToUTF8(value));
434*635a8641SAndroid Build Coastguard Worker   }
SetBool(StringPiece name,bool value)435*635a8641SAndroid Build Coastguard Worker   void SetBool(StringPiece name, bool value) {
436*635a8641SAndroid Build Coastguard Worker     char cvalue = value ? 1 : 0;
437*635a8641SAndroid Build Coastguard Worker     Set(name, BOOL_VALUE, &cvalue, sizeof(cvalue));
438*635a8641SAndroid Build Coastguard Worker   }
SetChar(StringPiece name,char value)439*635a8641SAndroid Build Coastguard Worker   void SetChar(StringPiece name, char value) {
440*635a8641SAndroid Build Coastguard Worker     Set(name, CHAR_VALUE, &value, sizeof(value));
441*635a8641SAndroid Build Coastguard Worker   }
SetInt(StringPiece name,int64_t value)442*635a8641SAndroid Build Coastguard Worker   void SetInt(StringPiece name, int64_t value) {
443*635a8641SAndroid Build Coastguard Worker     Set(name, SIGNED_VALUE, &value, sizeof(value));
444*635a8641SAndroid Build Coastguard Worker   }
SetUint(StringPiece name,uint64_t value)445*635a8641SAndroid Build Coastguard Worker   void SetUint(StringPiece name, uint64_t value) {
446*635a8641SAndroid Build Coastguard Worker     Set(name, UNSIGNED_VALUE, &value, sizeof(value));
447*635a8641SAndroid Build Coastguard Worker   }
448*635a8641SAndroid Build Coastguard Worker 
449*635a8641SAndroid Build Coastguard Worker   // These function as above but don't actually copy the data into the
450*635a8641SAndroid Build Coastguard Worker   // persistent memory. They store unaltered pointers along with a size. These
451*635a8641SAndroid Build Coastguard Worker   // can be used in conjuction with a memory dump to find certain large pieces
452*635a8641SAndroid Build Coastguard Worker   // of information.
SetReference(StringPiece name,const void * memory,size_t size)453*635a8641SAndroid Build Coastguard Worker   void SetReference(StringPiece name, const void* memory, size_t size) {
454*635a8641SAndroid Build Coastguard Worker     SetReference(name, RAW_VALUE_REFERENCE, memory, size);
455*635a8641SAndroid Build Coastguard Worker   }
SetStringReference(StringPiece name,StringPiece value)456*635a8641SAndroid Build Coastguard Worker   void SetStringReference(StringPiece name, StringPiece value) {
457*635a8641SAndroid Build Coastguard Worker     SetReference(name, STRING_VALUE_REFERENCE, value.data(), value.length());
458*635a8641SAndroid Build Coastguard Worker   }
459*635a8641SAndroid Build Coastguard Worker 
460*635a8641SAndroid Build Coastguard Worker   // Creates a snapshot of the key/value pairs contained within. The returned
461*635a8641SAndroid Build Coastguard Worker   // data will be fixed, independent of whatever changes afterward. There is
462*635a8641SAndroid Build Coastguard Worker   // some protection against concurrent modification. This will return false
463*635a8641SAndroid Build Coastguard Worker   // if the data is invalid or if a complete overwrite of the contents is
464*635a8641SAndroid Build Coastguard Worker   // detected.
465*635a8641SAndroid Build Coastguard Worker   bool CreateSnapshot(Snapshot* output_snapshot) const;
466*635a8641SAndroid Build Coastguard Worker 
467*635a8641SAndroid Build Coastguard Worker   // Gets the base memory address used for storing data.
468*635a8641SAndroid Build Coastguard Worker   const void* GetBaseAddress() const;
469*635a8641SAndroid Build Coastguard Worker 
470*635a8641SAndroid Build Coastguard Worker   // Explicitly sets the process ID.
471*635a8641SAndroid Build Coastguard Worker   void SetOwningProcessIdForTesting(int64_t pid, int64_t stamp);
472*635a8641SAndroid Build Coastguard Worker 
473*635a8641SAndroid Build Coastguard Worker   // Gets the associated process ID, in native form, and the creation timestamp
474*635a8641SAndroid Build Coastguard Worker   // from tracker memory without loading the entire structure for analysis. This
475*635a8641SAndroid Build Coastguard Worker   // will return false if no valid process ID is available.
476*635a8641SAndroid Build Coastguard Worker   static bool GetOwningProcessId(const void* memory,
477*635a8641SAndroid Build Coastguard Worker                                  int64_t* out_id,
478*635a8641SAndroid Build Coastguard Worker                                  int64_t* out_stamp);
479*635a8641SAndroid Build Coastguard Worker 
480*635a8641SAndroid Build Coastguard Worker  protected:
481*635a8641SAndroid Build Coastguard Worker   virtual void Set(StringPiece name,
482*635a8641SAndroid Build Coastguard Worker                    ValueType type,
483*635a8641SAndroid Build Coastguard Worker                    const void* memory,
484*635a8641SAndroid Build Coastguard Worker                    size_t size);
485*635a8641SAndroid Build Coastguard Worker 
486*635a8641SAndroid Build Coastguard Worker  private:
487*635a8641SAndroid Build Coastguard Worker   FRIEND_TEST_ALL_PREFIXES(ActivityTrackerTest, UserDataTest);
488*635a8641SAndroid Build Coastguard Worker 
489*635a8641SAndroid Build Coastguard Worker   enum : size_t { kMemoryAlignment = sizeof(uint64_t) };
490*635a8641SAndroid Build Coastguard Worker 
491*635a8641SAndroid Build Coastguard Worker   // A structure that defines the structure header in memory.
492*635a8641SAndroid Build Coastguard Worker   struct MemoryHeader {
493*635a8641SAndroid Build Coastguard Worker     MemoryHeader();
494*635a8641SAndroid Build Coastguard Worker     ~MemoryHeader();
495*635a8641SAndroid Build Coastguard Worker 
496*635a8641SAndroid Build Coastguard Worker     OwningProcess owner;  // Information about the creating process.
497*635a8641SAndroid Build Coastguard Worker   };
498*635a8641SAndroid Build Coastguard Worker 
499*635a8641SAndroid Build Coastguard Worker   // Header to a key/value record held in persistent memory.
500*635a8641SAndroid Build Coastguard Worker   struct FieldHeader {
501*635a8641SAndroid Build Coastguard Worker     FieldHeader();
502*635a8641SAndroid Build Coastguard Worker     ~FieldHeader();
503*635a8641SAndroid Build Coastguard Worker 
504*635a8641SAndroid Build Coastguard Worker     std::atomic<uint8_t> type;         // Encoded ValueType
505*635a8641SAndroid Build Coastguard Worker     uint8_t name_size;                 // Length of "name" key.
506*635a8641SAndroid Build Coastguard Worker     std::atomic<uint16_t> value_size;  // Actual size of of the stored value.
507*635a8641SAndroid Build Coastguard Worker     uint16_t record_size;              // Total storage of name, value, header.
508*635a8641SAndroid Build Coastguard Worker   };
509*635a8641SAndroid Build Coastguard Worker 
510*635a8641SAndroid Build Coastguard Worker   // A structure used to reference data held outside of persistent memory.
511*635a8641SAndroid Build Coastguard Worker   struct ReferenceRecord {
512*635a8641SAndroid Build Coastguard Worker     uint64_t address;
513*635a8641SAndroid Build Coastguard Worker     uint64_t size;
514*635a8641SAndroid Build Coastguard Worker   };
515*635a8641SAndroid Build Coastguard Worker 
516*635a8641SAndroid Build Coastguard Worker   // This record is used to hold known value is a map so that they can be
517*635a8641SAndroid Build Coastguard Worker   // found and overwritten later.
518*635a8641SAndroid Build Coastguard Worker   struct ValueInfo {
519*635a8641SAndroid Build Coastguard Worker     ValueInfo();
520*635a8641SAndroid Build Coastguard Worker     ValueInfo(ValueInfo&&);
521*635a8641SAndroid Build Coastguard Worker     ~ValueInfo();
522*635a8641SAndroid Build Coastguard Worker 
523*635a8641SAndroid Build Coastguard Worker     StringPiece name;                 // The "key" of the record.
524*635a8641SAndroid Build Coastguard Worker     ValueType type;                   // The type of the value.
525*635a8641SAndroid Build Coastguard Worker     void* memory;                     // Where the "value" is held.
526*635a8641SAndroid Build Coastguard Worker     std::atomic<uint16_t>* size_ptr;  // Address of the actual size of value.
527*635a8641SAndroid Build Coastguard Worker     size_t extent;                    // The total storage of the value,
528*635a8641SAndroid Build Coastguard Worker   };                                  // typically rounded up for alignment.
529*635a8641SAndroid Build Coastguard Worker 
530*635a8641SAndroid Build Coastguard Worker   void SetReference(StringPiece name,
531*635a8641SAndroid Build Coastguard Worker                     ValueType type,
532*635a8641SAndroid Build Coastguard Worker                     const void* memory,
533*635a8641SAndroid Build Coastguard Worker                     size_t size);
534*635a8641SAndroid Build Coastguard Worker 
535*635a8641SAndroid Build Coastguard Worker   // Loads any data already in the memory segment. This allows for accessing
536*635a8641SAndroid Build Coastguard Worker   // records created previously. If this detects that the underlying data has
537*635a8641SAndroid Build Coastguard Worker   // gone away (cleared by another thread/process), it will invalidate all the
538*635a8641SAndroid Build Coastguard Worker   // data in this object and turn it into simple "sink" with no values to
539*635a8641SAndroid Build Coastguard Worker   // return.
540*635a8641SAndroid Build Coastguard Worker   void ImportExistingData() const;
541*635a8641SAndroid Build Coastguard Worker 
542*635a8641SAndroid Build Coastguard Worker   // A map of all the values within the memory block, keyed by name for quick
543*635a8641SAndroid Build Coastguard Worker   // updates of the values. This is "mutable" because it changes on "const"
544*635a8641SAndroid Build Coastguard Worker   // objects even when the actual data values can't change.
545*635a8641SAndroid Build Coastguard Worker   mutable std::map<StringPiece, ValueInfo> values_;
546*635a8641SAndroid Build Coastguard Worker 
547*635a8641SAndroid Build Coastguard Worker   // Information about the memory block in which new data can be stored. These
548*635a8641SAndroid Build Coastguard Worker   // are "mutable" because they change even on "const" objects that are just
549*635a8641SAndroid Build Coastguard Worker   // skipping already set values.
550*635a8641SAndroid Build Coastguard Worker   mutable char* memory_;
551*635a8641SAndroid Build Coastguard Worker   mutable size_t available_;
552*635a8641SAndroid Build Coastguard Worker 
553*635a8641SAndroid Build Coastguard Worker   // A pointer to the memory header for this instance.
554*635a8641SAndroid Build Coastguard Worker   MemoryHeader* const header_;
555*635a8641SAndroid Build Coastguard Worker 
556*635a8641SAndroid Build Coastguard Worker   // These hold values used when initially creating the object. They are
557*635a8641SAndroid Build Coastguard Worker   // compared against current header values to check for outside changes.
558*635a8641SAndroid Build Coastguard Worker   const uint32_t orig_data_id;
559*635a8641SAndroid Build Coastguard Worker   const int64_t orig_process_id;
560*635a8641SAndroid Build Coastguard Worker   const int64_t orig_create_stamp;
561*635a8641SAndroid Build Coastguard Worker 
562*635a8641SAndroid Build Coastguard Worker   DISALLOW_COPY_AND_ASSIGN(ActivityUserData);
563*635a8641SAndroid Build Coastguard Worker };
564*635a8641SAndroid Build Coastguard Worker 
565*635a8641SAndroid Build Coastguard Worker // This class manages tracking a stack of activities for a single thread in
566*635a8641SAndroid Build Coastguard Worker // a persistent manner, implementing a bounded-size stack in a fixed-size
567*635a8641SAndroid Build Coastguard Worker // memory allocation. In order to support an operational mode where another
568*635a8641SAndroid Build Coastguard Worker // thread is analyzing this data in real-time, atomic operations are used
569*635a8641SAndroid Build Coastguard Worker // where necessary to guarantee a consistent view from the outside.
570*635a8641SAndroid Build Coastguard Worker //
571*635a8641SAndroid Build Coastguard Worker // This class is not generally used directly but instead managed by the
572*635a8641SAndroid Build Coastguard Worker // GlobalActivityTracker instance and updated using Scoped*Activity local
573*635a8641SAndroid Build Coastguard Worker // objects.
574*635a8641SAndroid Build Coastguard Worker class BASE_EXPORT ThreadActivityTracker {
575*635a8641SAndroid Build Coastguard Worker  public:
576*635a8641SAndroid Build Coastguard Worker   using ActivityId = uint32_t;
577*635a8641SAndroid Build Coastguard Worker 
578*635a8641SAndroid Build Coastguard Worker   // This structure contains all the common information about the thread so
579*635a8641SAndroid Build Coastguard Worker   // it doesn't have to be repeated in every entry on the stack. It is defined
580*635a8641SAndroid Build Coastguard Worker   // and used completely within the .cc file.
581*635a8641SAndroid Build Coastguard Worker   struct Header;
582*635a8641SAndroid Build Coastguard Worker 
583*635a8641SAndroid Build Coastguard Worker   // This structure holds a copy of all the internal data at the moment the
584*635a8641SAndroid Build Coastguard Worker   // "snapshot" operation is done. It is disconnected from the live tracker
585*635a8641SAndroid Build Coastguard Worker   // so that continued operation of the thread will not cause changes here.
586*635a8641SAndroid Build Coastguard Worker   struct BASE_EXPORT Snapshot {
587*635a8641SAndroid Build Coastguard Worker     // Explicit constructor/destructor are needed because of complex types
588*635a8641SAndroid Build Coastguard Worker     // with non-trivial default constructors and destructors.
589*635a8641SAndroid Build Coastguard Worker     Snapshot();
590*635a8641SAndroid Build Coastguard Worker     ~Snapshot();
591*635a8641SAndroid Build Coastguard Worker 
592*635a8641SAndroid Build Coastguard Worker     // The name of the thread as set when it was created. The name may be
593*635a8641SAndroid Build Coastguard Worker     // truncated due to internal length limitations.
594*635a8641SAndroid Build Coastguard Worker     std::string thread_name;
595*635a8641SAndroid Build Coastguard Worker 
596*635a8641SAndroid Build Coastguard Worker     // The timestamp at which this process was created.
597*635a8641SAndroid Build Coastguard Worker     int64_t create_stamp;
598*635a8641SAndroid Build Coastguard Worker 
599*635a8641SAndroid Build Coastguard Worker     // The process and thread IDs. These values have no meaning other than
600*635a8641SAndroid Build Coastguard Worker     // they uniquely identify a running process and a running thread within
601*635a8641SAndroid Build Coastguard Worker     // that process.  Thread-IDs can be re-used across different processes
602*635a8641SAndroid Build Coastguard Worker     // and both can be re-used after the process/thread exits.
603*635a8641SAndroid Build Coastguard Worker     int64_t process_id = 0;
604*635a8641SAndroid Build Coastguard Worker     int64_t thread_id = 0;
605*635a8641SAndroid Build Coastguard Worker 
606*635a8641SAndroid Build Coastguard Worker     // The current stack of activities that are underway for this thread. It
607*635a8641SAndroid Build Coastguard Worker     // is limited in its maximum size with later entries being left off.
608*635a8641SAndroid Build Coastguard Worker     std::vector<Activity> activity_stack;
609*635a8641SAndroid Build Coastguard Worker 
610*635a8641SAndroid Build Coastguard Worker     // The current total depth of the activity stack, including those later
611*635a8641SAndroid Build Coastguard Worker     // entries not recorded in the |activity_stack| vector.
612*635a8641SAndroid Build Coastguard Worker     uint32_t activity_stack_depth = 0;
613*635a8641SAndroid Build Coastguard Worker 
614*635a8641SAndroid Build Coastguard Worker     // The last recorded "exception" activity.
615*635a8641SAndroid Build Coastguard Worker     Activity last_exception;
616*635a8641SAndroid Build Coastguard Worker   };
617*635a8641SAndroid Build Coastguard Worker 
618*635a8641SAndroid Build Coastguard Worker   // This is the base class for having the compiler manage an activity on the
619*635a8641SAndroid Build Coastguard Worker   // tracker's stack. It does nothing but call methods on the passed |tracker|
620*635a8641SAndroid Build Coastguard Worker   // if it is not null, making it safe (and cheap) to create these objects
621*635a8641SAndroid Build Coastguard Worker   // even if activity tracking is not enabled.
622*635a8641SAndroid Build Coastguard Worker   class BASE_EXPORT ScopedActivity {
623*635a8641SAndroid Build Coastguard Worker    public:
624*635a8641SAndroid Build Coastguard Worker     ScopedActivity(ThreadActivityTracker* tracker,
625*635a8641SAndroid Build Coastguard Worker                    const void* program_counter,
626*635a8641SAndroid Build Coastguard Worker                    const void* origin,
627*635a8641SAndroid Build Coastguard Worker                    Activity::Type type,
628*635a8641SAndroid Build Coastguard Worker                    const ActivityData& data);
629*635a8641SAndroid Build Coastguard Worker     ~ScopedActivity();
630*635a8641SAndroid Build Coastguard Worker 
631*635a8641SAndroid Build Coastguard Worker     // Changes some basic metadata about the activity.
632*635a8641SAndroid Build Coastguard Worker     void ChangeTypeAndData(Activity::Type type, const ActivityData& data);
633*635a8641SAndroid Build Coastguard Worker 
634*635a8641SAndroid Build Coastguard Worker    protected:
635*635a8641SAndroid Build Coastguard Worker     // The thread tracker to which this object reports. It can be null if
636*635a8641SAndroid Build Coastguard Worker     // activity tracking is not (yet) enabled.
637*635a8641SAndroid Build Coastguard Worker     ThreadActivityTracker* const tracker_;
638*635a8641SAndroid Build Coastguard Worker 
639*635a8641SAndroid Build Coastguard Worker     // An identifier that indicates a specific activity on the stack.
640*635a8641SAndroid Build Coastguard Worker     ActivityId activity_id_;
641*635a8641SAndroid Build Coastguard Worker 
642*635a8641SAndroid Build Coastguard Worker    private:
643*635a8641SAndroid Build Coastguard Worker     DISALLOW_COPY_AND_ASSIGN(ScopedActivity);
644*635a8641SAndroid Build Coastguard Worker   };
645*635a8641SAndroid Build Coastguard Worker 
646*635a8641SAndroid Build Coastguard Worker   // A ThreadActivityTracker runs on top of memory that is managed externally.
647*635a8641SAndroid Build Coastguard Worker   // It must be large enough for the internal header and a few Activity
648*635a8641SAndroid Build Coastguard Worker   // blocks. See SizeForStackDepth().
649*635a8641SAndroid Build Coastguard Worker   ThreadActivityTracker(void* base, size_t size);
650*635a8641SAndroid Build Coastguard Worker   virtual ~ThreadActivityTracker();
651*635a8641SAndroid Build Coastguard Worker 
652*635a8641SAndroid Build Coastguard Worker   // Indicates that an activity has started from a given |origin| address in
653*635a8641SAndroid Build Coastguard Worker   // the code, though it can be null if the creator's address is not known.
654*635a8641SAndroid Build Coastguard Worker   // The |type| and |data| describe the activity. |program_counter| should be
655*635a8641SAndroid Build Coastguard Worker   // the result of GetProgramCounter() where push is called. Returned is an
656*635a8641SAndroid Build Coastguard Worker   // ID that can be used to adjust the pushed activity.
657*635a8641SAndroid Build Coastguard Worker   ActivityId PushActivity(const void* program_counter,
658*635a8641SAndroid Build Coastguard Worker                           const void* origin,
659*635a8641SAndroid Build Coastguard Worker                           Activity::Type type,
660*635a8641SAndroid Build Coastguard Worker                           const ActivityData& data);
661*635a8641SAndroid Build Coastguard Worker 
662*635a8641SAndroid Build Coastguard Worker   // An inlined version of the above that gets the program counter where it
663*635a8641SAndroid Build Coastguard Worker   // is called.
664*635a8641SAndroid Build Coastguard Worker   ALWAYS_INLINE
PushActivity(const void * origin,Activity::Type type,const ActivityData & data)665*635a8641SAndroid Build Coastguard Worker   ActivityId PushActivity(const void* origin,
666*635a8641SAndroid Build Coastguard Worker                           Activity::Type type,
667*635a8641SAndroid Build Coastguard Worker                           const ActivityData& data) {
668*635a8641SAndroid Build Coastguard Worker     return PushActivity(GetProgramCounter(), origin, type, data);
669*635a8641SAndroid Build Coastguard Worker   }
670*635a8641SAndroid Build Coastguard Worker 
671*635a8641SAndroid Build Coastguard Worker   // Changes the activity |type| and |data| of the top-most entry on the stack.
672*635a8641SAndroid Build Coastguard Worker   // This is useful if the information has changed and it is desireable to
673*635a8641SAndroid Build Coastguard Worker   // track that change without creating a new stack entry. If the type is
674*635a8641SAndroid Build Coastguard Worker   // ACT_NULL or the data is kNullActivityData then that value will remain
675*635a8641SAndroid Build Coastguard Worker   // unchanged. The type, if changed, must remain in the same category.
676*635a8641SAndroid Build Coastguard Worker   // Changing both is not atomic so a snapshot operation could occur between
677*635a8641SAndroid Build Coastguard Worker   // the update of |type| and |data| or between update of |data| fields.
678*635a8641SAndroid Build Coastguard Worker   void ChangeActivity(ActivityId id,
679*635a8641SAndroid Build Coastguard Worker                       Activity::Type type,
680*635a8641SAndroid Build Coastguard Worker                       const ActivityData& data);
681*635a8641SAndroid Build Coastguard Worker 
682*635a8641SAndroid Build Coastguard Worker   // Indicates that an activity has completed.
683*635a8641SAndroid Build Coastguard Worker   void PopActivity(ActivityId id);
684*635a8641SAndroid Build Coastguard Worker 
685*635a8641SAndroid Build Coastguard Worker   // Sets the user-data information for an activity.
686*635a8641SAndroid Build Coastguard Worker   std::unique_ptr<ActivityUserData> GetUserData(
687*635a8641SAndroid Build Coastguard Worker       ActivityId id,
688*635a8641SAndroid Build Coastguard Worker       ActivityTrackerMemoryAllocator* allocator);
689*635a8641SAndroid Build Coastguard Worker 
690*635a8641SAndroid Build Coastguard Worker   // Returns if there is true use-data associated with a given ActivityId since
691*635a8641SAndroid Build Coastguard Worker   // it's possible than any returned object is just a sink.
692*635a8641SAndroid Build Coastguard Worker   bool HasUserData(ActivityId id);
693*635a8641SAndroid Build Coastguard Worker 
694*635a8641SAndroid Build Coastguard Worker   // Release the user-data information for an activity.
695*635a8641SAndroid Build Coastguard Worker   void ReleaseUserData(ActivityId id,
696*635a8641SAndroid Build Coastguard Worker                        ActivityTrackerMemoryAllocator* allocator);
697*635a8641SAndroid Build Coastguard Worker 
698*635a8641SAndroid Build Coastguard Worker   // Save an exception. |origin| is the location of the exception.
699*635a8641SAndroid Build Coastguard Worker   void RecordExceptionActivity(const void* program_counter,
700*635a8641SAndroid Build Coastguard Worker                                const void* origin,
701*635a8641SAndroid Build Coastguard Worker                                Activity::Type type,
702*635a8641SAndroid Build Coastguard Worker                                const ActivityData& data);
703*635a8641SAndroid Build Coastguard Worker 
704*635a8641SAndroid Build Coastguard Worker   // Returns whether the current data is valid or not. It is not valid if
705*635a8641SAndroid Build Coastguard Worker   // corruption has been detected in the header or other data structures.
706*635a8641SAndroid Build Coastguard Worker   bool IsValid() const;
707*635a8641SAndroid Build Coastguard Worker 
708*635a8641SAndroid Build Coastguard Worker   // Gets a copy of the tracker contents for analysis. Returns false if a
709*635a8641SAndroid Build Coastguard Worker   // snapshot was not possible, perhaps because the data is not valid; the
710*635a8641SAndroid Build Coastguard Worker   // contents of |output_snapshot| are undefined in that case. The current
711*635a8641SAndroid Build Coastguard Worker   // implementation does not support concurrent snapshot operations.
712*635a8641SAndroid Build Coastguard Worker   bool CreateSnapshot(Snapshot* output_snapshot) const;
713*635a8641SAndroid Build Coastguard Worker 
714*635a8641SAndroid Build Coastguard Worker   // Gets the base memory address used for storing data.
715*635a8641SAndroid Build Coastguard Worker   const void* GetBaseAddress();
716*635a8641SAndroid Build Coastguard Worker 
717*635a8641SAndroid Build Coastguard Worker   // Access the "data version" value so tests can determine if an activity
718*635a8641SAndroid Build Coastguard Worker   // was pushed and popped in a single call.
719*635a8641SAndroid Build Coastguard Worker   uint32_t GetDataVersionForTesting();
720*635a8641SAndroid Build Coastguard Worker 
721*635a8641SAndroid Build Coastguard Worker   // Explicitly sets the process ID.
722*635a8641SAndroid Build Coastguard Worker   void SetOwningProcessIdForTesting(int64_t pid, int64_t stamp);
723*635a8641SAndroid Build Coastguard Worker 
724*635a8641SAndroid Build Coastguard Worker   // Gets the associated process ID, in native form, and the creation timestamp
725*635a8641SAndroid Build Coastguard Worker   // from tracker memory without loading the entire structure for analysis. This
726*635a8641SAndroid Build Coastguard Worker   // will return false if no valid process ID is available.
727*635a8641SAndroid Build Coastguard Worker   static bool GetOwningProcessId(const void* memory,
728*635a8641SAndroid Build Coastguard Worker                                  int64_t* out_id,
729*635a8641SAndroid Build Coastguard Worker                                  int64_t* out_stamp);
730*635a8641SAndroid Build Coastguard Worker 
731*635a8641SAndroid Build Coastguard Worker   // Calculates the memory size required for a given stack depth, including
732*635a8641SAndroid Build Coastguard Worker   // the internal header structure for the stack.
733*635a8641SAndroid Build Coastguard Worker   static size_t SizeForStackDepth(int stack_depth);
734*635a8641SAndroid Build Coastguard Worker 
735*635a8641SAndroid Build Coastguard Worker  private:
736*635a8641SAndroid Build Coastguard Worker   friend class ActivityTrackerTest;
737*635a8641SAndroid Build Coastguard Worker 
738*635a8641SAndroid Build Coastguard Worker   bool CalledOnValidThread();
739*635a8641SAndroid Build Coastguard Worker 
740*635a8641SAndroid Build Coastguard Worker   std::unique_ptr<ActivityUserData> CreateUserDataForActivity(
741*635a8641SAndroid Build Coastguard Worker       Activity* activity,
742*635a8641SAndroid Build Coastguard Worker       ActivityTrackerMemoryAllocator* allocator);
743*635a8641SAndroid Build Coastguard Worker 
744*635a8641SAndroid Build Coastguard Worker   Header* const header_;        // Pointer to the Header structure.
745*635a8641SAndroid Build Coastguard Worker   Activity* const stack_;       // The stack of activities.
746*635a8641SAndroid Build Coastguard Worker 
747*635a8641SAndroid Build Coastguard Worker #if DCHECK_IS_ON()
748*635a8641SAndroid Build Coastguard Worker   // The ActivityTracker is thread bound, and will be invoked across all the
749*635a8641SAndroid Build Coastguard Worker   // sequences that run on the thread. A ThreadChecker does not work here, as it
750*635a8641SAndroid Build Coastguard Worker   // asserts on running in the same sequence each time.
751*635a8641SAndroid Build Coastguard Worker   const PlatformThreadRef thread_id_;  // The thread this instance is bound to.
752*635a8641SAndroid Build Coastguard Worker #endif
753*635a8641SAndroid Build Coastguard Worker   const uint32_t stack_slots_;  // The total number of stack slots.
754*635a8641SAndroid Build Coastguard Worker 
755*635a8641SAndroid Build Coastguard Worker   bool valid_ = false;          // Tracks whether the data is valid or not.
756*635a8641SAndroid Build Coastguard Worker 
757*635a8641SAndroid Build Coastguard Worker   DISALLOW_COPY_AND_ASSIGN(ThreadActivityTracker);
758*635a8641SAndroid Build Coastguard Worker };
759*635a8641SAndroid Build Coastguard Worker 
760*635a8641SAndroid Build Coastguard Worker 
761*635a8641SAndroid Build Coastguard Worker // The global tracker manages all the individual thread trackers. Memory for
762*635a8641SAndroid Build Coastguard Worker // the thread trackers is taken from a PersistentMemoryAllocator which allows
763*635a8641SAndroid Build Coastguard Worker // for the data to be analyzed by a parallel process or even post-mortem.
764*635a8641SAndroid Build Coastguard Worker class BASE_EXPORT GlobalActivityTracker {
765*635a8641SAndroid Build Coastguard Worker  public:
766*635a8641SAndroid Build Coastguard Worker   // Type identifiers used when storing in persistent memory so they can be
767*635a8641SAndroid Build Coastguard Worker   // identified during extraction; the first 4 bytes of the SHA1 of the name
768*635a8641SAndroid Build Coastguard Worker   // is used as a unique integer. A "version number" is added to the base
769*635a8641SAndroid Build Coastguard Worker   // so that, if the structure of that object changes, stored older versions
770*635a8641SAndroid Build Coastguard Worker   // will be safely ignored. These are public so that an external process
771*635a8641SAndroid Build Coastguard Worker   // can recognize records of this type within an allocator.
772*635a8641SAndroid Build Coastguard Worker   enum : uint32_t {
773*635a8641SAndroid Build Coastguard Worker     kTypeIdActivityTracker = 0x5D7381AF + 4,   // SHA1(ActivityTracker) v4
774*635a8641SAndroid Build Coastguard Worker     kTypeIdUserDataRecord = 0x615EDDD7 + 3,    // SHA1(UserDataRecord) v3
775*635a8641SAndroid Build Coastguard Worker     kTypeIdGlobalLogMessage = 0x4CF434F9 + 1,  // SHA1(GlobalLogMessage) v1
776*635a8641SAndroid Build Coastguard Worker     kTypeIdProcessDataRecord = kTypeIdUserDataRecord + 0x100,
777*635a8641SAndroid Build Coastguard Worker 
778*635a8641SAndroid Build Coastguard Worker     kTypeIdActivityTrackerFree = ~kTypeIdActivityTracker,
779*635a8641SAndroid Build Coastguard Worker     kTypeIdUserDataRecordFree = ~kTypeIdUserDataRecord,
780*635a8641SAndroid Build Coastguard Worker     kTypeIdProcessDataRecordFree = ~kTypeIdProcessDataRecord,
781*635a8641SAndroid Build Coastguard Worker   };
782*635a8641SAndroid Build Coastguard Worker 
783*635a8641SAndroid Build Coastguard Worker   // An enumeration of common process life stages. All entries are given an
784*635a8641SAndroid Build Coastguard Worker   // explicit number so they are known and remain constant; this allows for
785*635a8641SAndroid Build Coastguard Worker   // cross-version analysis either locally or on a server.
786*635a8641SAndroid Build Coastguard Worker   enum ProcessPhase : int {
787*635a8641SAndroid Build Coastguard Worker     // The phases are generic and may have meaning to the tracker.
788*635a8641SAndroid Build Coastguard Worker     PROCESS_PHASE_UNKNOWN = 0,
789*635a8641SAndroid Build Coastguard Worker     PROCESS_LAUNCHED = 1,
790*635a8641SAndroid Build Coastguard Worker     PROCESS_LAUNCH_FAILED = 2,
791*635a8641SAndroid Build Coastguard Worker     PROCESS_EXITED_CLEANLY = 10,
792*635a8641SAndroid Build Coastguard Worker     PROCESS_EXITED_WITH_CODE = 11,
793*635a8641SAndroid Build Coastguard Worker 
794*635a8641SAndroid Build Coastguard Worker     // Add here whatever is useful for analysis.
795*635a8641SAndroid Build Coastguard Worker     PROCESS_SHUTDOWN_STARTED = 100,
796*635a8641SAndroid Build Coastguard Worker     PROCESS_MAIN_LOOP_STARTED = 101,
797*635a8641SAndroid Build Coastguard Worker   };
798*635a8641SAndroid Build Coastguard Worker 
799*635a8641SAndroid Build Coastguard Worker   // A callback made when a process exits to allow immediate analysis of its
800*635a8641SAndroid Build Coastguard Worker   // data. Note that the system may reuse the |process_id| so when fetching
801*635a8641SAndroid Build Coastguard Worker   // records it's important to ensure that what is returned was created before
802*635a8641SAndroid Build Coastguard Worker   // the |exit_stamp|. Movement of |process_data| information is allowed.
803*635a8641SAndroid Build Coastguard Worker   using ProcessExitCallback =
804*635a8641SAndroid Build Coastguard Worker       Callback<void(int64_t process_id,
805*635a8641SAndroid Build Coastguard Worker                     int64_t exit_stamp,
806*635a8641SAndroid Build Coastguard Worker                     int exit_code,
807*635a8641SAndroid Build Coastguard Worker                     ProcessPhase exit_phase,
808*635a8641SAndroid Build Coastguard Worker                     std::string&& command_line,
809*635a8641SAndroid Build Coastguard Worker                     ActivityUserData::Snapshot&& process_data)>;
810*635a8641SAndroid Build Coastguard Worker 
811*635a8641SAndroid Build Coastguard Worker   // This structure contains information about a loaded module, as shown to
812*635a8641SAndroid Build Coastguard Worker   // users of the tracker.
813*635a8641SAndroid Build Coastguard Worker   struct BASE_EXPORT ModuleInfo {
814*635a8641SAndroid Build Coastguard Worker     ModuleInfo();
815*635a8641SAndroid Build Coastguard Worker     ModuleInfo(ModuleInfo&& rhs);
816*635a8641SAndroid Build Coastguard Worker     ModuleInfo(const ModuleInfo& rhs);
817*635a8641SAndroid Build Coastguard Worker     ~ModuleInfo();
818*635a8641SAndroid Build Coastguard Worker 
819*635a8641SAndroid Build Coastguard Worker     ModuleInfo& operator=(ModuleInfo&& rhs);
820*635a8641SAndroid Build Coastguard Worker     ModuleInfo& operator=(const ModuleInfo& rhs);
821*635a8641SAndroid Build Coastguard Worker 
822*635a8641SAndroid Build Coastguard Worker     // Information about where and when the module was loaded/unloaded.
823*635a8641SAndroid Build Coastguard Worker     bool is_loaded = false;  // Was the last operation a load or unload?
824*635a8641SAndroid Build Coastguard Worker     uintptr_t address = 0;   // Address of the last load operation.
825*635a8641SAndroid Build Coastguard Worker     int64_t load_time = 0;   // Time of last change; set automatically.
826*635a8641SAndroid Build Coastguard Worker 
827*635a8641SAndroid Build Coastguard Worker     // Information about the module itself. These never change no matter how
828*635a8641SAndroid Build Coastguard Worker     // many times a module may be loaded and unloaded.
829*635a8641SAndroid Build Coastguard Worker     size_t size = 0;         // The size of the loaded module.
830*635a8641SAndroid Build Coastguard Worker     uint32_t timestamp = 0;  // Opaque "timestamp" for the module.
831*635a8641SAndroid Build Coastguard Worker     uint32_t age = 0;        // Opaque "age" for the module.
832*635a8641SAndroid Build Coastguard Worker     uint8_t identifier[16];  // Opaque identifier (GUID, etc.) for the module.
833*635a8641SAndroid Build Coastguard Worker     std::string file;        // The full path to the file. (UTF-8)
834*635a8641SAndroid Build Coastguard Worker     std::string debug_file;  // The full path to the debug file.
835*635a8641SAndroid Build Coastguard Worker   };
836*635a8641SAndroid Build Coastguard Worker 
837*635a8641SAndroid Build Coastguard Worker   // This is a thin wrapper around the thread-tracker's ScopedActivity that
838*635a8641SAndroid Build Coastguard Worker   // allows thread-safe access to data values. It is safe to use even if
839*635a8641SAndroid Build Coastguard Worker   // activity tracking is not enabled.
840*635a8641SAndroid Build Coastguard Worker   class BASE_EXPORT ScopedThreadActivity
841*635a8641SAndroid Build Coastguard Worker       : public ThreadActivityTracker::ScopedActivity {
842*635a8641SAndroid Build Coastguard Worker    public:
843*635a8641SAndroid Build Coastguard Worker     ScopedThreadActivity(const void* program_counter,
844*635a8641SAndroid Build Coastguard Worker                          const void* origin,
845*635a8641SAndroid Build Coastguard Worker                          Activity::Type type,
846*635a8641SAndroid Build Coastguard Worker                          const ActivityData& data,
847*635a8641SAndroid Build Coastguard Worker                          bool lock_allowed);
848*635a8641SAndroid Build Coastguard Worker     ~ScopedThreadActivity();
849*635a8641SAndroid Build Coastguard Worker 
850*635a8641SAndroid Build Coastguard Worker     // Returns an object for manipulating user data.
851*635a8641SAndroid Build Coastguard Worker     ActivityUserData& user_data();
852*635a8641SAndroid Build Coastguard Worker 
853*635a8641SAndroid Build Coastguard Worker    private:
854*635a8641SAndroid Build Coastguard Worker     // Gets (or creates) a tracker for the current thread. If locking is not
855*635a8641SAndroid Build Coastguard Worker     // allowed (because a lock is being tracked which would cause recursion)
856*635a8641SAndroid Build Coastguard Worker     // then the attempt to create one if none found will be skipped. Once
857*635a8641SAndroid Build Coastguard Worker     // the tracker for this thread has been created for other reasons, locks
858*635a8641SAndroid Build Coastguard Worker     // will be tracked. The thread-tracker uses locks.
GetOrCreateTracker(bool lock_allowed)859*635a8641SAndroid Build Coastguard Worker     static ThreadActivityTracker* GetOrCreateTracker(bool lock_allowed) {
860*635a8641SAndroid Build Coastguard Worker       GlobalActivityTracker* global_tracker = Get();
861*635a8641SAndroid Build Coastguard Worker       if (!global_tracker)
862*635a8641SAndroid Build Coastguard Worker         return nullptr;
863*635a8641SAndroid Build Coastguard Worker 
864*635a8641SAndroid Build Coastguard Worker       // It is not safe to use TLS once TLS has been destroyed. This can happen
865*635a8641SAndroid Build Coastguard Worker       // if code that runs late during thread destruction tries to use a
866*635a8641SAndroid Build Coastguard Worker       // base::Lock. See https://crbug.com/864589.
867*635a8641SAndroid Build Coastguard Worker       if (base::ThreadLocalStorage::HasBeenDestroyed())
868*635a8641SAndroid Build Coastguard Worker         return nullptr;
869*635a8641SAndroid Build Coastguard Worker 
870*635a8641SAndroid Build Coastguard Worker       if (lock_allowed)
871*635a8641SAndroid Build Coastguard Worker         return global_tracker->GetOrCreateTrackerForCurrentThread();
872*635a8641SAndroid Build Coastguard Worker       else
873*635a8641SAndroid Build Coastguard Worker         return global_tracker->GetTrackerForCurrentThread();
874*635a8641SAndroid Build Coastguard Worker     }
875*635a8641SAndroid Build Coastguard Worker 
876*635a8641SAndroid Build Coastguard Worker     // An object that manages additional user data, created only upon request.
877*635a8641SAndroid Build Coastguard Worker     std::unique_ptr<ActivityUserData> user_data_;
878*635a8641SAndroid Build Coastguard Worker 
879*635a8641SAndroid Build Coastguard Worker     DISALLOW_COPY_AND_ASSIGN(ScopedThreadActivity);
880*635a8641SAndroid Build Coastguard Worker   };
881*635a8641SAndroid Build Coastguard Worker 
882*635a8641SAndroid Build Coastguard Worker   ~GlobalActivityTracker();
883*635a8641SAndroid Build Coastguard Worker 
884*635a8641SAndroid Build Coastguard Worker   // Creates a global tracker using a given persistent-memory |allocator| and
885*635a8641SAndroid Build Coastguard Worker   // providing the given |stack_depth| to each thread tracker it manages. The
886*635a8641SAndroid Build Coastguard Worker   // created object is activated so tracking will begin immediately upon return.
887*635a8641SAndroid Build Coastguard Worker   // The |process_id| can be zero to get it from the OS but is taken for testing
888*635a8641SAndroid Build Coastguard Worker   // purposes.
889*635a8641SAndroid Build Coastguard Worker   static void CreateWithAllocator(
890*635a8641SAndroid Build Coastguard Worker       std::unique_ptr<PersistentMemoryAllocator> allocator,
891*635a8641SAndroid Build Coastguard Worker       int stack_depth,
892*635a8641SAndroid Build Coastguard Worker       int64_t process_id);
893*635a8641SAndroid Build Coastguard Worker 
894*635a8641SAndroid Build Coastguard Worker #if !defined(OS_NACL)
895*635a8641SAndroid Build Coastguard Worker   // Like above but internally creates an allocator around a disk file with
896*635a8641SAndroid Build Coastguard Worker   // the specified |size| at the given |file_path|. Any existing file will be
897*635a8641SAndroid Build Coastguard Worker   // overwritten. The |id| and |name| are arbitrary and stored in the allocator
898*635a8641SAndroid Build Coastguard Worker   // for reference by whatever process reads it. Returns true if successful.
899*635a8641SAndroid Build Coastguard Worker   static bool CreateWithFile(const FilePath& file_path,
900*635a8641SAndroid Build Coastguard Worker                              size_t size,
901*635a8641SAndroid Build Coastguard Worker                              uint64_t id,
902*635a8641SAndroid Build Coastguard Worker                              StringPiece name,
903*635a8641SAndroid Build Coastguard Worker                              int stack_depth);
904*635a8641SAndroid Build Coastguard Worker #endif  // !defined(OS_NACL)
905*635a8641SAndroid Build Coastguard Worker 
906*635a8641SAndroid Build Coastguard Worker   // Like above but internally creates an allocator using local heap memory of
907*635a8641SAndroid Build Coastguard Worker   // the specified size. This is used primarily for unit tests. The |process_id|
908*635a8641SAndroid Build Coastguard Worker   // can be zero to get it from the OS but is taken for testing purposes.
909*635a8641SAndroid Build Coastguard Worker   static bool CreateWithLocalMemory(size_t size,
910*635a8641SAndroid Build Coastguard Worker                                     uint64_t id,
911*635a8641SAndroid Build Coastguard Worker                                     StringPiece name,
912*635a8641SAndroid Build Coastguard Worker                                     int stack_depth,
913*635a8641SAndroid Build Coastguard Worker                                     int64_t process_id);
914*635a8641SAndroid Build Coastguard Worker 
915*635a8641SAndroid Build Coastguard Worker   // Like above but internally creates an allocator using a shared-memory
916*635a8641SAndroid Build Coastguard Worker   // segment. The segment must already be mapped into the local memory space.
917*635a8641SAndroid Build Coastguard Worker   static bool CreateWithSharedMemory(std::unique_ptr<SharedMemory> shm,
918*635a8641SAndroid Build Coastguard Worker                                      uint64_t id,
919*635a8641SAndroid Build Coastguard Worker                                      StringPiece name,
920*635a8641SAndroid Build Coastguard Worker                                      int stack_depth);
921*635a8641SAndroid Build Coastguard Worker 
922*635a8641SAndroid Build Coastguard Worker   // Like above but takes a handle to an existing shared memory segment and
923*635a8641SAndroid Build Coastguard Worker   // maps it before creating the tracker.
924*635a8641SAndroid Build Coastguard Worker   static bool CreateWithSharedMemoryHandle(const SharedMemoryHandle& handle,
925*635a8641SAndroid Build Coastguard Worker                                            size_t size,
926*635a8641SAndroid Build Coastguard Worker                                            uint64_t id,
927*635a8641SAndroid Build Coastguard Worker                                            StringPiece name,
928*635a8641SAndroid Build Coastguard Worker                                            int stack_depth);
929*635a8641SAndroid Build Coastguard Worker 
930*635a8641SAndroid Build Coastguard Worker   // Gets the global activity-tracker or null if none exists.
Get()931*635a8641SAndroid Build Coastguard Worker   static GlobalActivityTracker* Get() {
932*635a8641SAndroid Build Coastguard Worker     return reinterpret_cast<GlobalActivityTracker*>(
933*635a8641SAndroid Build Coastguard Worker         subtle::Acquire_Load(&g_tracker_));
934*635a8641SAndroid Build Coastguard Worker   }
935*635a8641SAndroid Build Coastguard Worker 
936*635a8641SAndroid Build Coastguard Worker   // Sets the global activity-tracker for testing purposes.
937*635a8641SAndroid Build Coastguard Worker   static void SetForTesting(std::unique_ptr<GlobalActivityTracker> tracker);
938*635a8641SAndroid Build Coastguard Worker 
939*635a8641SAndroid Build Coastguard Worker   // This access to the persistent allocator is only for testing; it extracts
940*635a8641SAndroid Build Coastguard Worker   // the global tracker completely. All tracked threads must exit before
941*635a8641SAndroid Build Coastguard Worker   // calling this. Tracking for the current thread will be automatically
942*635a8641SAndroid Build Coastguard Worker   // stopped.
943*635a8641SAndroid Build Coastguard Worker   static std::unique_ptr<GlobalActivityTracker> ReleaseForTesting();
944*635a8641SAndroid Build Coastguard Worker 
945*635a8641SAndroid Build Coastguard Worker   // Convenience method for determining if a global tracker is active.
IsEnabled()946*635a8641SAndroid Build Coastguard Worker   static bool IsEnabled() { return Get() != nullptr; }
947*635a8641SAndroid Build Coastguard Worker 
948*635a8641SAndroid Build Coastguard Worker   // Gets the persistent-memory-allocator in which data is stored. Callers
949*635a8641SAndroid Build Coastguard Worker   // can store additional records here to pass more information to the
950*635a8641SAndroid Build Coastguard Worker   // analysis process.
allocator()951*635a8641SAndroid Build Coastguard Worker   PersistentMemoryAllocator* allocator() { return allocator_.get(); }
952*635a8641SAndroid Build Coastguard Worker 
953*635a8641SAndroid Build Coastguard Worker   // Gets the thread's activity-tracker if it exists. This is inline for
954*635a8641SAndroid Build Coastguard Worker   // performance reasons and it uses thread-local-storage (TLS) so that there
955*635a8641SAndroid Build Coastguard Worker   // is no significant lookup time required to find the one for the calling
956*635a8641SAndroid Build Coastguard Worker   // thread. Ownership remains with the global tracker.
GetTrackerForCurrentThread()957*635a8641SAndroid Build Coastguard Worker   ThreadActivityTracker* GetTrackerForCurrentThread() {
958*635a8641SAndroid Build Coastguard Worker     return reinterpret_cast<ThreadActivityTracker*>(this_thread_tracker_.Get());
959*635a8641SAndroid Build Coastguard Worker   }
960*635a8641SAndroid Build Coastguard Worker 
961*635a8641SAndroid Build Coastguard Worker   // Gets the thread's activity-tracker or creates one if none exists. This
962*635a8641SAndroid Build Coastguard Worker   // is inline for performance reasons. Ownership remains with the global
963*635a8641SAndroid Build Coastguard Worker   // tracker.
GetOrCreateTrackerForCurrentThread()964*635a8641SAndroid Build Coastguard Worker   ThreadActivityTracker* GetOrCreateTrackerForCurrentThread() {
965*635a8641SAndroid Build Coastguard Worker     ThreadActivityTracker* tracker = GetTrackerForCurrentThread();
966*635a8641SAndroid Build Coastguard Worker     if (tracker)
967*635a8641SAndroid Build Coastguard Worker       return tracker;
968*635a8641SAndroid Build Coastguard Worker     return CreateTrackerForCurrentThread();
969*635a8641SAndroid Build Coastguard Worker   }
970*635a8641SAndroid Build Coastguard Worker 
971*635a8641SAndroid Build Coastguard Worker   // Creates an activity-tracker for the current thread.
972*635a8641SAndroid Build Coastguard Worker   ThreadActivityTracker* CreateTrackerForCurrentThread();
973*635a8641SAndroid Build Coastguard Worker 
974*635a8641SAndroid Build Coastguard Worker   // Releases the activity-tracker for the current thread (for testing only).
975*635a8641SAndroid Build Coastguard Worker   void ReleaseTrackerForCurrentThreadForTesting();
976*635a8641SAndroid Build Coastguard Worker 
977*635a8641SAndroid Build Coastguard Worker   // Sets a task-runner that can be used for background work.
978*635a8641SAndroid Build Coastguard Worker   void SetBackgroundTaskRunner(const scoped_refptr<TaskRunner>& runner);
979*635a8641SAndroid Build Coastguard Worker 
980*635a8641SAndroid Build Coastguard Worker   // Sets an optional callback to be called when a process exits.
981*635a8641SAndroid Build Coastguard Worker   void SetProcessExitCallback(ProcessExitCallback callback);
982*635a8641SAndroid Build Coastguard Worker 
983*635a8641SAndroid Build Coastguard Worker   // Manages process lifetimes. These are called by the process that launched
984*635a8641SAndroid Build Coastguard Worker   // and reaped the subprocess, not the subprocess itself. If it is expensive
985*635a8641SAndroid Build Coastguard Worker   // to generate the parameters, Get() the global tracker and call these
986*635a8641SAndroid Build Coastguard Worker   // conditionally rather than using the static versions.
987*635a8641SAndroid Build Coastguard Worker   void RecordProcessLaunch(ProcessId process_id,
988*635a8641SAndroid Build Coastguard Worker                            const FilePath::StringType& cmd);
989*635a8641SAndroid Build Coastguard Worker   void RecordProcessLaunch(ProcessId process_id,
990*635a8641SAndroid Build Coastguard Worker                            const FilePath::StringType& exe,
991*635a8641SAndroid Build Coastguard Worker                            const FilePath::StringType& args);
992*635a8641SAndroid Build Coastguard Worker   void RecordProcessExit(ProcessId process_id, int exit_code);
RecordProcessLaunchIfEnabled(ProcessId process_id,const FilePath::StringType & cmd)993*635a8641SAndroid Build Coastguard Worker   static void RecordProcessLaunchIfEnabled(ProcessId process_id,
994*635a8641SAndroid Build Coastguard Worker                                            const FilePath::StringType& cmd) {
995*635a8641SAndroid Build Coastguard Worker     GlobalActivityTracker* tracker = Get();
996*635a8641SAndroid Build Coastguard Worker     if (tracker)
997*635a8641SAndroid Build Coastguard Worker       tracker->RecordProcessLaunch(process_id, cmd);
998*635a8641SAndroid Build Coastguard Worker   }
RecordProcessLaunchIfEnabled(ProcessId process_id,const FilePath::StringType & exe,const FilePath::StringType & args)999*635a8641SAndroid Build Coastguard Worker   static void RecordProcessLaunchIfEnabled(ProcessId process_id,
1000*635a8641SAndroid Build Coastguard Worker                                            const FilePath::StringType& exe,
1001*635a8641SAndroid Build Coastguard Worker                                            const FilePath::StringType& args) {
1002*635a8641SAndroid Build Coastguard Worker     GlobalActivityTracker* tracker = Get();
1003*635a8641SAndroid Build Coastguard Worker     if (tracker)
1004*635a8641SAndroid Build Coastguard Worker       tracker->RecordProcessLaunch(process_id, exe, args);
1005*635a8641SAndroid Build Coastguard Worker   }
RecordProcessExitIfEnabled(ProcessId process_id,int exit_code)1006*635a8641SAndroid Build Coastguard Worker   static void RecordProcessExitIfEnabled(ProcessId process_id, int exit_code) {
1007*635a8641SAndroid Build Coastguard Worker     GlobalActivityTracker* tracker = Get();
1008*635a8641SAndroid Build Coastguard Worker     if (tracker)
1009*635a8641SAndroid Build Coastguard Worker       tracker->RecordProcessExit(process_id, exit_code);
1010*635a8641SAndroid Build Coastguard Worker   }
1011*635a8641SAndroid Build Coastguard Worker 
1012*635a8641SAndroid Build Coastguard Worker   // Sets the "phase" of the current process, useful for knowing what it was
1013*635a8641SAndroid Build Coastguard Worker   // doing when it last reported.
1014*635a8641SAndroid Build Coastguard Worker   void SetProcessPhase(ProcessPhase phase);
SetProcessPhaseIfEnabled(ProcessPhase phase)1015*635a8641SAndroid Build Coastguard Worker   static void SetProcessPhaseIfEnabled(ProcessPhase phase) {
1016*635a8641SAndroid Build Coastguard Worker     GlobalActivityTracker* tracker = Get();
1017*635a8641SAndroid Build Coastguard Worker     if (tracker)
1018*635a8641SAndroid Build Coastguard Worker       tracker->SetProcessPhase(phase);
1019*635a8641SAndroid Build Coastguard Worker   }
1020*635a8641SAndroid Build Coastguard Worker 
1021*635a8641SAndroid Build Coastguard Worker   // Records a log message. The current implementation does NOT recycle these
1022*635a8641SAndroid Build Coastguard Worker   // only store critical messages such as FATAL ones.
1023*635a8641SAndroid Build Coastguard Worker   void RecordLogMessage(StringPiece message);
RecordLogMessageIfEnabled(StringPiece message)1024*635a8641SAndroid Build Coastguard Worker   static void RecordLogMessageIfEnabled(StringPiece message) {
1025*635a8641SAndroid Build Coastguard Worker     GlobalActivityTracker* tracker = Get();
1026*635a8641SAndroid Build Coastguard Worker     if (tracker)
1027*635a8641SAndroid Build Coastguard Worker       tracker->RecordLogMessage(message);
1028*635a8641SAndroid Build Coastguard Worker   }
1029*635a8641SAndroid Build Coastguard Worker 
1030*635a8641SAndroid Build Coastguard Worker   // Records a module load/unload event. This is safe to call multiple times
1031*635a8641SAndroid Build Coastguard Worker   // even with the same information.
1032*635a8641SAndroid Build Coastguard Worker   void RecordModuleInfo(const ModuleInfo& info);
RecordModuleInfoIfEnabled(const ModuleInfo & info)1033*635a8641SAndroid Build Coastguard Worker   static void RecordModuleInfoIfEnabled(const ModuleInfo& info) {
1034*635a8641SAndroid Build Coastguard Worker     GlobalActivityTracker* tracker = Get();
1035*635a8641SAndroid Build Coastguard Worker     if (tracker)
1036*635a8641SAndroid Build Coastguard Worker       tracker->RecordModuleInfo(info);
1037*635a8641SAndroid Build Coastguard Worker   }
1038*635a8641SAndroid Build Coastguard Worker 
1039*635a8641SAndroid Build Coastguard Worker   // Record field trial information. This call is thread-safe. In addition to
1040*635a8641SAndroid Build Coastguard Worker   // this, construction of a GlobalActivityTracker will cause all existing
1041*635a8641SAndroid Build Coastguard Worker   // active field trials to be fetched and recorded.
1042*635a8641SAndroid Build Coastguard Worker   void RecordFieldTrial(const std::string& trial_name, StringPiece group_name);
RecordFieldTrialIfEnabled(const std::string & trial_name,StringPiece group_name)1043*635a8641SAndroid Build Coastguard Worker   static void RecordFieldTrialIfEnabled(const std::string& trial_name,
1044*635a8641SAndroid Build Coastguard Worker                                         StringPiece group_name) {
1045*635a8641SAndroid Build Coastguard Worker     GlobalActivityTracker* tracker = Get();
1046*635a8641SAndroid Build Coastguard Worker     if (tracker)
1047*635a8641SAndroid Build Coastguard Worker       tracker->RecordFieldTrial(trial_name, group_name);
1048*635a8641SAndroid Build Coastguard Worker   }
1049*635a8641SAndroid Build Coastguard Worker 
1050*635a8641SAndroid Build Coastguard Worker   // Record exception information for the current thread.
1051*635a8641SAndroid Build Coastguard Worker   ALWAYS_INLINE
RecordException(const void * origin,uint32_t code)1052*635a8641SAndroid Build Coastguard Worker   void RecordException(const void* origin, uint32_t code) {
1053*635a8641SAndroid Build Coastguard Worker     return RecordExceptionImpl(GetProgramCounter(), origin, code);
1054*635a8641SAndroid Build Coastguard Worker   }
1055*635a8641SAndroid Build Coastguard Worker   void RecordException(const void* pc, const void* origin, uint32_t code);
1056*635a8641SAndroid Build Coastguard Worker 
1057*635a8641SAndroid Build Coastguard Worker   // Marks the tracked data as deleted.
1058*635a8641SAndroid Build Coastguard Worker   void MarkDeleted();
1059*635a8641SAndroid Build Coastguard Worker 
1060*635a8641SAndroid Build Coastguard Worker   // Gets the process ID used for tracking. This is typically the same as what
1061*635a8641SAndroid Build Coastguard Worker   // the OS thinks is the current process but can be overridden for testing.
process_id()1062*635a8641SAndroid Build Coastguard Worker   int64_t process_id() { return process_id_; }
1063*635a8641SAndroid Build Coastguard Worker 
1064*635a8641SAndroid Build Coastguard Worker   // Accesses the process data record for storing arbitrary key/value pairs.
1065*635a8641SAndroid Build Coastguard Worker   // Updates to this are thread-safe.
process_data()1066*635a8641SAndroid Build Coastguard Worker   ActivityUserData& process_data() { return process_data_; }
1067*635a8641SAndroid Build Coastguard Worker 
1068*635a8641SAndroid Build Coastguard Worker  private:
1069*635a8641SAndroid Build Coastguard Worker   friend class GlobalActivityAnalyzer;
1070*635a8641SAndroid Build Coastguard Worker   friend class ScopedThreadActivity;
1071*635a8641SAndroid Build Coastguard Worker   friend class ActivityTrackerTest;
1072*635a8641SAndroid Build Coastguard Worker 
1073*635a8641SAndroid Build Coastguard Worker   enum : int {
1074*635a8641SAndroid Build Coastguard Worker     // The maximum number of threads that can be tracked within a process. If
1075*635a8641SAndroid Build Coastguard Worker     // more than this number run concurrently, tracking of new ones may cease.
1076*635a8641SAndroid Build Coastguard Worker     kMaxThreadCount = 100,
1077*635a8641SAndroid Build Coastguard Worker     kCachedThreadMemories = 10,
1078*635a8641SAndroid Build Coastguard Worker     kCachedUserDataMemories = 10,
1079*635a8641SAndroid Build Coastguard Worker   };
1080*635a8641SAndroid Build Coastguard Worker 
1081*635a8641SAndroid Build Coastguard Worker   // A wrapper around ActivityUserData that is thread-safe and thus can be used
1082*635a8641SAndroid Build Coastguard Worker   // in the global scope without the requirement of being called from only one
1083*635a8641SAndroid Build Coastguard Worker   // thread.
1084*635a8641SAndroid Build Coastguard Worker   class ThreadSafeUserData : public ActivityUserData {
1085*635a8641SAndroid Build Coastguard Worker    public:
1086*635a8641SAndroid Build Coastguard Worker     ThreadSafeUserData(void* memory, size_t size, int64_t pid = 0);
1087*635a8641SAndroid Build Coastguard Worker     ~ThreadSafeUserData() override;
1088*635a8641SAndroid Build Coastguard Worker 
1089*635a8641SAndroid Build Coastguard Worker    private:
1090*635a8641SAndroid Build Coastguard Worker     void Set(StringPiece name,
1091*635a8641SAndroid Build Coastguard Worker              ValueType type,
1092*635a8641SAndroid Build Coastguard Worker              const void* memory,
1093*635a8641SAndroid Build Coastguard Worker              size_t size) override;
1094*635a8641SAndroid Build Coastguard Worker 
1095*635a8641SAndroid Build Coastguard Worker     Lock data_lock_;
1096*635a8641SAndroid Build Coastguard Worker 
1097*635a8641SAndroid Build Coastguard Worker     DISALLOW_COPY_AND_ASSIGN(ThreadSafeUserData);
1098*635a8641SAndroid Build Coastguard Worker   };
1099*635a8641SAndroid Build Coastguard Worker 
1100*635a8641SAndroid Build Coastguard Worker   // State of a module as stored in persistent memory. This supports a single
1101*635a8641SAndroid Build Coastguard Worker   // loading of a module only. If modules are loaded multiple times at
1102*635a8641SAndroid Build Coastguard Worker   // different addresses, only the last will be recorded and an unload will
1103*635a8641SAndroid Build Coastguard Worker   // not revert to the information of any other addresses.
1104*635a8641SAndroid Build Coastguard Worker   struct BASE_EXPORT ModuleInfoRecord {
1105*635a8641SAndroid Build Coastguard Worker     // SHA1(ModuleInfoRecord): Increment this if structure changes!
1106*635a8641SAndroid Build Coastguard Worker     static constexpr uint32_t kPersistentTypeId = 0x05DB5F41 + 1;
1107*635a8641SAndroid Build Coastguard Worker 
1108*635a8641SAndroid Build Coastguard Worker     // Expected size for 32/64-bit check by PersistentMemoryAllocator.
1109*635a8641SAndroid Build Coastguard Worker     static constexpr size_t kExpectedInstanceSize =
1110*635a8641SAndroid Build Coastguard Worker         OwningProcess::kExpectedInstanceSize + 56;
1111*635a8641SAndroid Build Coastguard Worker 
1112*635a8641SAndroid Build Coastguard Worker     // The atomic unfortunately makes this a "complex" class on some compilers
1113*635a8641SAndroid Build Coastguard Worker     // and thus requires an out-of-line constructor & destructor even though
1114*635a8641SAndroid Build Coastguard Worker     // they do nothing.
1115*635a8641SAndroid Build Coastguard Worker     ModuleInfoRecord();
1116*635a8641SAndroid Build Coastguard Worker     ~ModuleInfoRecord();
1117*635a8641SAndroid Build Coastguard Worker 
1118*635a8641SAndroid Build Coastguard Worker     OwningProcess owner;            // The process that created this record.
1119*635a8641SAndroid Build Coastguard Worker     uint64_t address;               // The base address of the module.
1120*635a8641SAndroid Build Coastguard Worker     uint64_t load_time;             // Time of last load/unload.
1121*635a8641SAndroid Build Coastguard Worker     uint64_t size;                  // The size of the module in bytes.
1122*635a8641SAndroid Build Coastguard Worker     uint32_t timestamp;             // Opaque timestamp of the module.
1123*635a8641SAndroid Build Coastguard Worker     uint32_t age;                   // Opaque "age" associated with the module.
1124*635a8641SAndroid Build Coastguard Worker     uint8_t identifier[16];         // Opaque identifier for the module.
1125*635a8641SAndroid Build Coastguard Worker     std::atomic<uint32_t> changes;  // Number load/unload actions.
1126*635a8641SAndroid Build Coastguard Worker     uint16_t pickle_size;           // The size of the following pickle.
1127*635a8641SAndroid Build Coastguard Worker     uint8_t loaded;                 // Flag if module is loaded or not.
1128*635a8641SAndroid Build Coastguard Worker     char pickle[1];                 // Other strings; may allocate larger.
1129*635a8641SAndroid Build Coastguard Worker 
1130*635a8641SAndroid Build Coastguard Worker     // Decodes/encodes storage structure from more generic info structure.
1131*635a8641SAndroid Build Coastguard Worker     bool DecodeTo(GlobalActivityTracker::ModuleInfo* info,
1132*635a8641SAndroid Build Coastguard Worker                   size_t record_size) const;
1133*635a8641SAndroid Build Coastguard Worker     static ModuleInfoRecord* CreateFrom(
1134*635a8641SAndroid Build Coastguard Worker         const GlobalActivityTracker::ModuleInfo& info,
1135*635a8641SAndroid Build Coastguard Worker         PersistentMemoryAllocator* allocator);
1136*635a8641SAndroid Build Coastguard Worker 
1137*635a8641SAndroid Build Coastguard Worker     // Updates the core information without changing the encoded strings. This
1138*635a8641SAndroid Build Coastguard Worker     // is useful when a known module changes state (i.e. new load or unload).
1139*635a8641SAndroid Build Coastguard Worker     bool UpdateFrom(const GlobalActivityTracker::ModuleInfo& info);
1140*635a8641SAndroid Build Coastguard Worker 
1141*635a8641SAndroid Build Coastguard Worker    private:
1142*635a8641SAndroid Build Coastguard Worker     DISALLOW_COPY_AND_ASSIGN(ModuleInfoRecord);
1143*635a8641SAndroid Build Coastguard Worker   };
1144*635a8641SAndroid Build Coastguard Worker 
1145*635a8641SAndroid Build Coastguard Worker   // A thin wrapper around the main thread-tracker that keeps additional
1146*635a8641SAndroid Build Coastguard Worker   // information that the global tracker needs to handle joined threads.
1147*635a8641SAndroid Build Coastguard Worker   class ManagedActivityTracker : public ThreadActivityTracker {
1148*635a8641SAndroid Build Coastguard Worker    public:
1149*635a8641SAndroid Build Coastguard Worker     ManagedActivityTracker(PersistentMemoryAllocator::Reference mem_reference,
1150*635a8641SAndroid Build Coastguard Worker                            void* base,
1151*635a8641SAndroid Build Coastguard Worker                            size_t size);
1152*635a8641SAndroid Build Coastguard Worker     ~ManagedActivityTracker() override;
1153*635a8641SAndroid Build Coastguard Worker 
1154*635a8641SAndroid Build Coastguard Worker     // The reference into persistent memory from which the thread-tracker's
1155*635a8641SAndroid Build Coastguard Worker     // memory was created.
1156*635a8641SAndroid Build Coastguard Worker     const PersistentMemoryAllocator::Reference mem_reference_;
1157*635a8641SAndroid Build Coastguard Worker 
1158*635a8641SAndroid Build Coastguard Worker     // The physical address used for the thread-tracker's memory.
1159*635a8641SAndroid Build Coastguard Worker     void* const mem_base_;
1160*635a8641SAndroid Build Coastguard Worker 
1161*635a8641SAndroid Build Coastguard Worker    private:
1162*635a8641SAndroid Build Coastguard Worker     DISALLOW_COPY_AND_ASSIGN(ManagedActivityTracker);
1163*635a8641SAndroid Build Coastguard Worker   };
1164*635a8641SAndroid Build Coastguard Worker 
1165*635a8641SAndroid Build Coastguard Worker   // Creates a global tracker using a given persistent-memory |allocator| and
1166*635a8641SAndroid Build Coastguard Worker   // providing the given |stack_depth| to each thread tracker it manages. The
1167*635a8641SAndroid Build Coastguard Worker   // created object is activated so tracking has already started upon return.
1168*635a8641SAndroid Build Coastguard Worker   // The |process_id| can be zero to get it from the OS but is taken for testing
1169*635a8641SAndroid Build Coastguard Worker   // purposes.
1170*635a8641SAndroid Build Coastguard Worker   GlobalActivityTracker(std::unique_ptr<PersistentMemoryAllocator> allocator,
1171*635a8641SAndroid Build Coastguard Worker                         int stack_depth,
1172*635a8641SAndroid Build Coastguard Worker                         int64_t process_id);
1173*635a8641SAndroid Build Coastguard Worker 
1174*635a8641SAndroid Build Coastguard Worker   // Returns the memory used by an activity-tracker managed by this class.
1175*635a8641SAndroid Build Coastguard Worker   // It is called during the destruction of a ManagedActivityTracker object.
1176*635a8641SAndroid Build Coastguard Worker   void ReturnTrackerMemory(ManagedActivityTracker* tracker);
1177*635a8641SAndroid Build Coastguard Worker 
1178*635a8641SAndroid Build Coastguard Worker   // Records exception information.
1179*635a8641SAndroid Build Coastguard Worker   void RecordExceptionImpl(const void* pc, const void* origin, uint32_t code);
1180*635a8641SAndroid Build Coastguard Worker 
1181*635a8641SAndroid Build Coastguard Worker   // Releases the activity-tracker associcated with thread. It is called
1182*635a8641SAndroid Build Coastguard Worker   // automatically when a thread is joined and thus there is nothing more to
1183*635a8641SAndroid Build Coastguard Worker   // be tracked. |value| is a pointer to a ManagedActivityTracker.
1184*635a8641SAndroid Build Coastguard Worker   static void OnTLSDestroy(void* value);
1185*635a8641SAndroid Build Coastguard Worker 
1186*635a8641SAndroid Build Coastguard Worker   // Does process-exit work. This can be run on any thread.
1187*635a8641SAndroid Build Coastguard Worker   void CleanupAfterProcess(int64_t process_id,
1188*635a8641SAndroid Build Coastguard Worker                            int64_t exit_stamp,
1189*635a8641SAndroid Build Coastguard Worker                            int exit_code,
1190*635a8641SAndroid Build Coastguard Worker                            std::string&& command_line);
1191*635a8641SAndroid Build Coastguard Worker 
1192*635a8641SAndroid Build Coastguard Worker   // The persistent-memory allocator from which the memory for all trackers
1193*635a8641SAndroid Build Coastguard Worker   // is taken.
1194*635a8641SAndroid Build Coastguard Worker   std::unique_ptr<PersistentMemoryAllocator> allocator_;
1195*635a8641SAndroid Build Coastguard Worker 
1196*635a8641SAndroid Build Coastguard Worker   // The size (in bytes) of memory required by a ThreadActivityTracker to
1197*635a8641SAndroid Build Coastguard Worker   // provide the stack-depth requested during construction.
1198*635a8641SAndroid Build Coastguard Worker   const size_t stack_memory_size_;
1199*635a8641SAndroid Build Coastguard Worker 
1200*635a8641SAndroid Build Coastguard Worker   // The process-id of the current process. This is kept as a member variable,
1201*635a8641SAndroid Build Coastguard Worker   // defined during initialization, for testing purposes.
1202*635a8641SAndroid Build Coastguard Worker   const int64_t process_id_;
1203*635a8641SAndroid Build Coastguard Worker 
1204*635a8641SAndroid Build Coastguard Worker   // The activity tracker for the currently executing thread.
1205*635a8641SAndroid Build Coastguard Worker   ThreadLocalStorage::Slot this_thread_tracker_;
1206*635a8641SAndroid Build Coastguard Worker 
1207*635a8641SAndroid Build Coastguard Worker   // The number of thread trackers currently active.
1208*635a8641SAndroid Build Coastguard Worker   std::atomic<int> thread_tracker_count_;
1209*635a8641SAndroid Build Coastguard Worker 
1210*635a8641SAndroid Build Coastguard Worker   // A caching memory allocator for thread-tracker objects.
1211*635a8641SAndroid Build Coastguard Worker   ActivityTrackerMemoryAllocator thread_tracker_allocator_;
1212*635a8641SAndroid Build Coastguard Worker   Lock thread_tracker_allocator_lock_;
1213*635a8641SAndroid Build Coastguard Worker 
1214*635a8641SAndroid Build Coastguard Worker   // A caching memory allocator for user data attached to activity data.
1215*635a8641SAndroid Build Coastguard Worker   ActivityTrackerMemoryAllocator user_data_allocator_;
1216*635a8641SAndroid Build Coastguard Worker   Lock user_data_allocator_lock_;
1217*635a8641SAndroid Build Coastguard Worker 
1218*635a8641SAndroid Build Coastguard Worker   // An object for holding arbitrary key value pairs with thread-safe access.
1219*635a8641SAndroid Build Coastguard Worker   ThreadSafeUserData process_data_;
1220*635a8641SAndroid Build Coastguard Worker 
1221*635a8641SAndroid Build Coastguard Worker   // A map of global module information, keyed by module path.
1222*635a8641SAndroid Build Coastguard Worker   std::map<const std::string, ModuleInfoRecord*> modules_;
1223*635a8641SAndroid Build Coastguard Worker   Lock modules_lock_;
1224*635a8641SAndroid Build Coastguard Worker 
1225*635a8641SAndroid Build Coastguard Worker   // The active global activity tracker.
1226*635a8641SAndroid Build Coastguard Worker   static subtle::AtomicWord g_tracker_;
1227*635a8641SAndroid Build Coastguard Worker 
1228*635a8641SAndroid Build Coastguard Worker   // A lock that is used to protect access to the following fields.
1229*635a8641SAndroid Build Coastguard Worker   Lock global_tracker_lock_;
1230*635a8641SAndroid Build Coastguard Worker 
1231*635a8641SAndroid Build Coastguard Worker   // The collection of processes being tracked and their command-lines.
1232*635a8641SAndroid Build Coastguard Worker   std::map<int64_t, std::string> known_processes_;
1233*635a8641SAndroid Build Coastguard Worker 
1234*635a8641SAndroid Build Coastguard Worker   // A task-runner that can be used for doing background processing.
1235*635a8641SAndroid Build Coastguard Worker   scoped_refptr<TaskRunner> background_task_runner_;
1236*635a8641SAndroid Build Coastguard Worker 
1237*635a8641SAndroid Build Coastguard Worker   // A callback performed when a subprocess exits, including its exit-code
1238*635a8641SAndroid Build Coastguard Worker   // and the phase it was in when that occurred. This will be called via
1239*635a8641SAndroid Build Coastguard Worker   // the |background_task_runner_| if one is set or whatever thread reaped
1240*635a8641SAndroid Build Coastguard Worker   // the process otherwise.
1241*635a8641SAndroid Build Coastguard Worker   ProcessExitCallback process_exit_callback_;
1242*635a8641SAndroid Build Coastguard Worker 
1243*635a8641SAndroid Build Coastguard Worker   DISALLOW_COPY_AND_ASSIGN(GlobalActivityTracker);
1244*635a8641SAndroid Build Coastguard Worker };
1245*635a8641SAndroid Build Coastguard Worker 
1246*635a8641SAndroid Build Coastguard Worker 
1247*635a8641SAndroid Build Coastguard Worker // Record entry in to and out of an arbitrary block of code.
1248*635a8641SAndroid Build Coastguard Worker class BASE_EXPORT ScopedActivity
1249*635a8641SAndroid Build Coastguard Worker     : public GlobalActivityTracker::ScopedThreadActivity {
1250*635a8641SAndroid Build Coastguard Worker  public:
1251*635a8641SAndroid Build Coastguard Worker   // Track activity at the specified FROM_HERE location for an arbitrary
1252*635a8641SAndroid Build Coastguard Worker   // 4-bit |action|, an arbitrary 32-bit |id|, and 32-bits of arbitrary
1253*635a8641SAndroid Build Coastguard Worker   // |info|. None of these values affect operation; they're all purely
1254*635a8641SAndroid Build Coastguard Worker   // for association and analysis. To have unique identifiers across a
1255*635a8641SAndroid Build Coastguard Worker   // diverse code-base, create the number by taking the first 8 characters
1256*635a8641SAndroid Build Coastguard Worker   // of the hash of the activity being tracked.
1257*635a8641SAndroid Build Coastguard Worker   //
1258*635a8641SAndroid Build Coastguard Worker   // For example:
1259*635a8641SAndroid Build Coastguard Worker   //   Tracking method: void MayNeverExit(uint32_t foo) {...}
1260*635a8641SAndroid Build Coastguard Worker   //   echo -n "MayNeverExit" | sha1sum   =>   e44873ccab21e2b71270da24aa1...
1261*635a8641SAndroid Build Coastguard Worker   //
1262*635a8641SAndroid Build Coastguard Worker   //   void MayNeverExit(int32_t foo) {
1263*635a8641SAndroid Build Coastguard Worker   //     base::debug::ScopedActivity track_me(0, 0xE44873CC, foo);
1264*635a8641SAndroid Build Coastguard Worker   //     ...
1265*635a8641SAndroid Build Coastguard Worker   //   }
1266*635a8641SAndroid Build Coastguard Worker   ALWAYS_INLINE
ScopedActivity(uint8_t action,uint32_t id,int32_t info)1267*635a8641SAndroid Build Coastguard Worker   ScopedActivity(uint8_t action, uint32_t id, int32_t info)
1268*635a8641SAndroid Build Coastguard Worker       : ScopedActivity(GetProgramCounter(), action, id, info) {}
ScopedActivity()1269*635a8641SAndroid Build Coastguard Worker   ScopedActivity() : ScopedActivity(0, 0, 0) {}
1270*635a8641SAndroid Build Coastguard Worker 
1271*635a8641SAndroid Build Coastguard Worker   // Changes the |action| and/or |info| of this activity on the stack. This
1272*635a8641SAndroid Build Coastguard Worker   // is useful for tracking progress through a function, updating the action
1273*635a8641SAndroid Build Coastguard Worker   // to indicate "milestones" in the block (max 16 milestones: 0-15) or the
1274*635a8641SAndroid Build Coastguard Worker   // info to reflect other changes. Changing both is not atomic so a snapshot
1275*635a8641SAndroid Build Coastguard Worker   // operation could occur between the update of |action| and |info|.
1276*635a8641SAndroid Build Coastguard Worker   void ChangeAction(uint8_t action);
1277*635a8641SAndroid Build Coastguard Worker   void ChangeInfo(int32_t info);
1278*635a8641SAndroid Build Coastguard Worker   void ChangeActionAndInfo(uint8_t action, int32_t info);
1279*635a8641SAndroid Build Coastguard Worker 
1280*635a8641SAndroid Build Coastguard Worker  private:
1281*635a8641SAndroid Build Coastguard Worker   // Constructs the object using a passed-in program-counter.
1282*635a8641SAndroid Build Coastguard Worker   ScopedActivity(const void* program_counter,
1283*635a8641SAndroid Build Coastguard Worker                  uint8_t action,
1284*635a8641SAndroid Build Coastguard Worker                  uint32_t id,
1285*635a8641SAndroid Build Coastguard Worker                  int32_t info);
1286*635a8641SAndroid Build Coastguard Worker 
1287*635a8641SAndroid Build Coastguard Worker   // A copy of the ID code so it doesn't have to be passed by the caller when
1288*635a8641SAndroid Build Coastguard Worker   // changing the |info| field.
1289*635a8641SAndroid Build Coastguard Worker   uint32_t id_;
1290*635a8641SAndroid Build Coastguard Worker 
1291*635a8641SAndroid Build Coastguard Worker   DISALLOW_COPY_AND_ASSIGN(ScopedActivity);
1292*635a8641SAndroid Build Coastguard Worker };
1293*635a8641SAndroid Build Coastguard Worker 
1294*635a8641SAndroid Build Coastguard Worker 
1295*635a8641SAndroid Build Coastguard Worker // These "scoped" classes provide easy tracking of various blocking actions.
1296*635a8641SAndroid Build Coastguard Worker 
1297*635a8641SAndroid Build Coastguard Worker class BASE_EXPORT ScopedTaskRunActivity
1298*635a8641SAndroid Build Coastguard Worker     : public GlobalActivityTracker::ScopedThreadActivity {
1299*635a8641SAndroid Build Coastguard Worker  public:
1300*635a8641SAndroid Build Coastguard Worker   ALWAYS_INLINE
ScopedTaskRunActivity(const PendingTask & task)1301*635a8641SAndroid Build Coastguard Worker   explicit ScopedTaskRunActivity(const PendingTask& task)
1302*635a8641SAndroid Build Coastguard Worker       : ScopedTaskRunActivity(GetProgramCounter(), task) {}
1303*635a8641SAndroid Build Coastguard Worker 
1304*635a8641SAndroid Build Coastguard Worker  private:
1305*635a8641SAndroid Build Coastguard Worker   ScopedTaskRunActivity(const void* program_counter, const PendingTask& task);
1306*635a8641SAndroid Build Coastguard Worker   DISALLOW_COPY_AND_ASSIGN(ScopedTaskRunActivity);
1307*635a8641SAndroid Build Coastguard Worker };
1308*635a8641SAndroid Build Coastguard Worker 
1309*635a8641SAndroid Build Coastguard Worker class BASE_EXPORT ScopedLockAcquireActivity
1310*635a8641SAndroid Build Coastguard Worker     : public GlobalActivityTracker::ScopedThreadActivity {
1311*635a8641SAndroid Build Coastguard Worker  public:
1312*635a8641SAndroid Build Coastguard Worker   ALWAYS_INLINE
ScopedLockAcquireActivity(const base::internal::LockImpl * lock)1313*635a8641SAndroid Build Coastguard Worker   explicit ScopedLockAcquireActivity(const base::internal::LockImpl* lock)
1314*635a8641SAndroid Build Coastguard Worker       : ScopedLockAcquireActivity(GetProgramCounter(), lock) {}
1315*635a8641SAndroid Build Coastguard Worker 
1316*635a8641SAndroid Build Coastguard Worker  private:
1317*635a8641SAndroid Build Coastguard Worker   ScopedLockAcquireActivity(const void* program_counter,
1318*635a8641SAndroid Build Coastguard Worker                             const base::internal::LockImpl* lock);
1319*635a8641SAndroid Build Coastguard Worker   DISALLOW_COPY_AND_ASSIGN(ScopedLockAcquireActivity);
1320*635a8641SAndroid Build Coastguard Worker };
1321*635a8641SAndroid Build Coastguard Worker 
1322*635a8641SAndroid Build Coastguard Worker class BASE_EXPORT ScopedEventWaitActivity
1323*635a8641SAndroid Build Coastguard Worker     : public GlobalActivityTracker::ScopedThreadActivity {
1324*635a8641SAndroid Build Coastguard Worker  public:
1325*635a8641SAndroid Build Coastguard Worker   ALWAYS_INLINE
ScopedEventWaitActivity(const WaitableEvent * event)1326*635a8641SAndroid Build Coastguard Worker   explicit ScopedEventWaitActivity(const WaitableEvent* event)
1327*635a8641SAndroid Build Coastguard Worker       : ScopedEventWaitActivity(GetProgramCounter(), event) {}
1328*635a8641SAndroid Build Coastguard Worker 
1329*635a8641SAndroid Build Coastguard Worker  private:
1330*635a8641SAndroid Build Coastguard Worker   ScopedEventWaitActivity(const void* program_counter,
1331*635a8641SAndroid Build Coastguard Worker                           const WaitableEvent* event);
1332*635a8641SAndroid Build Coastguard Worker   DISALLOW_COPY_AND_ASSIGN(ScopedEventWaitActivity);
1333*635a8641SAndroid Build Coastguard Worker };
1334*635a8641SAndroid Build Coastguard Worker 
1335*635a8641SAndroid Build Coastguard Worker class BASE_EXPORT ScopedThreadJoinActivity
1336*635a8641SAndroid Build Coastguard Worker     : public GlobalActivityTracker::ScopedThreadActivity {
1337*635a8641SAndroid Build Coastguard Worker  public:
1338*635a8641SAndroid Build Coastguard Worker   ALWAYS_INLINE
ScopedThreadJoinActivity(const PlatformThreadHandle * thread)1339*635a8641SAndroid Build Coastguard Worker   explicit ScopedThreadJoinActivity(const PlatformThreadHandle* thread)
1340*635a8641SAndroid Build Coastguard Worker       : ScopedThreadJoinActivity(GetProgramCounter(), thread) {}
1341*635a8641SAndroid Build Coastguard Worker 
1342*635a8641SAndroid Build Coastguard Worker  private:
1343*635a8641SAndroid Build Coastguard Worker   ScopedThreadJoinActivity(const void* program_counter,
1344*635a8641SAndroid Build Coastguard Worker                            const PlatformThreadHandle* thread);
1345*635a8641SAndroid Build Coastguard Worker   DISALLOW_COPY_AND_ASSIGN(ScopedThreadJoinActivity);
1346*635a8641SAndroid Build Coastguard Worker };
1347*635a8641SAndroid Build Coastguard Worker 
1348*635a8641SAndroid Build Coastguard Worker // Some systems don't have base::Process
1349*635a8641SAndroid Build Coastguard Worker #if !defined(OS_NACL) && !defined(OS_IOS)
1350*635a8641SAndroid Build Coastguard Worker class BASE_EXPORT ScopedProcessWaitActivity
1351*635a8641SAndroid Build Coastguard Worker     : public GlobalActivityTracker::ScopedThreadActivity {
1352*635a8641SAndroid Build Coastguard Worker  public:
1353*635a8641SAndroid Build Coastguard Worker   ALWAYS_INLINE
ScopedProcessWaitActivity(const Process * process)1354*635a8641SAndroid Build Coastguard Worker   explicit ScopedProcessWaitActivity(const Process* process)
1355*635a8641SAndroid Build Coastguard Worker       : ScopedProcessWaitActivity(GetProgramCounter(), process) {}
1356*635a8641SAndroid Build Coastguard Worker 
1357*635a8641SAndroid Build Coastguard Worker  private:
1358*635a8641SAndroid Build Coastguard Worker   ScopedProcessWaitActivity(const void* program_counter,
1359*635a8641SAndroid Build Coastguard Worker                             const Process* process);
1360*635a8641SAndroid Build Coastguard Worker   DISALLOW_COPY_AND_ASSIGN(ScopedProcessWaitActivity);
1361*635a8641SAndroid Build Coastguard Worker };
1362*635a8641SAndroid Build Coastguard Worker #endif
1363*635a8641SAndroid Build Coastguard Worker 
1364*635a8641SAndroid Build Coastguard Worker }  // namespace debug
1365*635a8641SAndroid Build Coastguard Worker }  // namespace base
1366*635a8641SAndroid Build Coastguard Worker 
1367*635a8641SAndroid Build Coastguard Worker #endif  // BASE_DEBUG_ACTIVITY_TRACKER_H_
1368