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