Home | History | Annotate | Download | only in debug
      1 // Copyright 2016 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "base/debug/activity_tracker.h"
      6 
      7 #include <algorithm>
      8 #include <limits>
      9 #include <utility>
     10 
     11 #include "base/atomic_sequence_num.h"
     12 #include "base/debug/stack_trace.h"
     13 #include "base/files/file.h"
     14 #include "base/files/file_path.h"
     15 #include "base/files/memory_mapped_file.h"
     16 #include "base/logging.h"
     17 #include "base/memory/ptr_util.h"
     18 #include "base/metrics/field_trial.h"
     19 #include "base/metrics/histogram_macros.h"
     20 #include "base/pending_task.h"
     21 #include "base/pickle.h"
     22 #include "base/process/process.h"
     23 #include "base/process/process_handle.h"
     24 #include "base/stl_util.h"
     25 #include "base/strings/string_util.h"
     26 #include "base/strings/utf_string_conversions.h"
     27 #include "base/threading/platform_thread.h"
     28 #include "build/build_config.h"
     29 
     30 namespace base {
     31 namespace debug {
     32 
     33 namespace {
     34 
     35 // The minimum depth a stack should support.
     36 const int kMinStackDepth = 2;
     37 
     38 // The amount of memory set aside for holding arbitrary user data (key/value
     39 // pairs) globally or associated with ActivityData entries.
     40 const size_t kUserDataSize = 1 << 10;     // 1 KiB
     41 const size_t kProcessDataSize = 4 << 10;  // 4 KiB
     42 const size_t kMaxUserDataNameLength =
     43     static_cast<size_t>(std::numeric_limits<uint8_t>::max());
     44 
     45 // A constant used to indicate that module information is changing.
     46 const uint32_t kModuleInformationChanging = 0x80000000;
     47 
     48 // The key used to record process information.
     49 const char kProcessPhaseDataKey[] = "process-phase";
     50 
     51 // An atomically incrementing number, used to check for recreations of objects
     52 // in the same memory space.
     53 AtomicSequenceNumber g_next_id;
     54 
     55 // Gets the next non-zero identifier. It is only unique within a process.
     56 uint32_t GetNextDataId() {
     57   uint32_t id;
     58   while ((id = g_next_id.GetNext()) == 0)
     59     ;
     60   return id;
     61 }
     62 
     63 // Gets the current process-id, either from the GlobalActivityTracker if it
     64 // exists (where the PID can be defined for testing) or from the system if
     65 // there isn't such.
     66 int64_t GetProcessId() {
     67   GlobalActivityTracker* global = GlobalActivityTracker::Get();
     68   if (global)
     69     return global->process_id();
     70   return GetCurrentProcId();
     71 }
     72 
     73 // Finds and reuses a specific allocation or creates a new one.
     74 PersistentMemoryAllocator::Reference AllocateFrom(
     75     PersistentMemoryAllocator* allocator,
     76     uint32_t from_type,
     77     size_t size,
     78     uint32_t to_type) {
     79   PersistentMemoryAllocator::Iterator iter(allocator);
     80   PersistentMemoryAllocator::Reference ref;
     81   while ((ref = iter.GetNextOfType(from_type)) != 0) {
     82     DCHECK_LE(size, allocator->GetAllocSize(ref));
     83     // This can fail if a another thread has just taken it. It is assumed that
     84     // the memory is cleared during the "free" operation.
     85     if (allocator->ChangeType(ref, to_type, from_type, /*clear=*/false))
     86       return ref;
     87   }
     88 
     89   return allocator->Allocate(size, to_type);
     90 }
     91 
     92 // Determines the previous aligned index.
     93 size_t RoundDownToAlignment(size_t index, size_t alignment) {
     94   return index & (0 - alignment);
     95 }
     96 
     97 // Determines the next aligned index.
     98 size_t RoundUpToAlignment(size_t index, size_t alignment) {
     99   return (index + (alignment - 1)) & (0 - alignment);
    100 }
    101 
    102 // Converts "tick" timing into wall time.
    103 Time WallTimeFromTickTime(int64_t ticks_start, int64_t ticks, Time time_start) {
    104   return time_start + TimeDelta::FromInternalValue(ticks - ticks_start);
    105 }
    106 
    107 }  // namespace
    108 
    109 union ThreadRef {
    110   int64_t as_id;
    111 #if defined(OS_WIN)
    112   // On Windows, the handle itself is often a pseudo-handle with a common
    113   // value meaning "this thread" and so the thread-id is used. The former
    114   // can be converted to a thread-id with a system call.
    115   PlatformThreadId as_tid;
    116 #elif defined(OS_POSIX) || defined(OS_FUCHSIA)
    117   // On Posix and Fuchsia, the handle is always a unique identifier so no
    118   // conversion needs to be done. However, its value is officially opaque so
    119   // there is no one correct way to convert it to a numerical identifier.
    120   PlatformThreadHandle::Handle as_handle;
    121 #endif
    122 };
    123 
    124 OwningProcess::OwningProcess() = default;
    125 OwningProcess::~OwningProcess() = default;
    126 
    127 void OwningProcess::Release_Initialize(int64_t pid) {
    128   uint32_t old_id = data_id.load(std::memory_order_acquire);
    129   DCHECK_EQ(0U, old_id);
    130   process_id = pid != 0 ? pid : GetProcessId();
    131   create_stamp = Time::Now().ToInternalValue();
    132   data_id.store(GetNextDataId(), std::memory_order_release);
    133 }
    134 
    135 void OwningProcess::SetOwningProcessIdForTesting(int64_t pid, int64_t stamp) {
    136   DCHECK_NE(0U, data_id);
    137   process_id = pid;
    138   create_stamp = stamp;
    139 }
    140 
    141 // static
    142 bool OwningProcess::GetOwningProcessId(const void* memory,
    143                                        int64_t* out_id,
    144                                        int64_t* out_stamp) {
    145   const OwningProcess* info = reinterpret_cast<const OwningProcess*>(memory);
    146   uint32_t id = info->data_id.load(std::memory_order_acquire);
    147   if (id == 0)
    148     return false;
    149 
    150   *out_id = info->process_id;
    151   *out_stamp = info->create_stamp;
    152   return id == info->data_id.load(std::memory_order_seq_cst);
    153 }
    154 
    155 // It doesn't matter what is contained in this (though it will be all zeros)
    156 // as only the address of it is important.
    157 const ActivityData kNullActivityData = {};
    158 
    159 ActivityData ActivityData::ForThread(const PlatformThreadHandle& handle) {
    160   ThreadRef thread_ref;
    161   thread_ref.as_id = 0;  // Zero the union in case other is smaller.
    162 #if defined(OS_WIN)
    163   thread_ref.as_tid = ::GetThreadId(handle.platform_handle());
    164 #elif defined(OS_POSIX)
    165   thread_ref.as_handle = handle.platform_handle();
    166 #endif
    167   return ForThread(thread_ref.as_id);
    168 }
    169 
    170 ActivityTrackerMemoryAllocator::ActivityTrackerMemoryAllocator(
    171     PersistentMemoryAllocator* allocator,
    172     uint32_t object_type,
    173     uint32_t object_free_type,
    174     size_t object_size,
    175     size_t cache_size,
    176     bool make_iterable)
    177     : allocator_(allocator),
    178       object_type_(object_type),
    179       object_free_type_(object_free_type),
    180       object_size_(object_size),
    181       cache_size_(cache_size),
    182       make_iterable_(make_iterable),
    183       iterator_(allocator),
    184       cache_values_(new Reference[cache_size]),
    185       cache_used_(0) {
    186   DCHECK(allocator);
    187 }
    188 
    189 ActivityTrackerMemoryAllocator::~ActivityTrackerMemoryAllocator() = default;
    190 
    191 ActivityTrackerMemoryAllocator::Reference
    192 ActivityTrackerMemoryAllocator::GetObjectReference() {
    193   // First see if there is a cached value that can be returned. This is much
    194   // faster than searching the memory system for free blocks.
    195   while (cache_used_ > 0) {
    196     Reference cached = cache_values_[--cache_used_];
    197     // Change the type of the cached object to the proper type and return it.
    198     // If the type-change fails that means another thread has taken this from
    199     // under us (via the search below) so ignore it and keep trying. Don't
    200     // clear the memory because that was done when the type was made "free".
    201     if (allocator_->ChangeType(cached, object_type_, object_free_type_, false))
    202       return cached;
    203   }
    204 
    205   // Fetch the next "free" object from persistent memory. Rather than restart
    206   // the iterator at the head each time and likely waste time going again
    207   // through objects that aren't relevant, the iterator continues from where
    208   // it last left off and is only reset when the end is reached. If the
    209   // returned reference matches |last|, then it has wrapped without finding
    210   // anything.
    211   const Reference last = iterator_.GetLast();
    212   while (true) {
    213     uint32_t type;
    214     Reference found = iterator_.GetNext(&type);
    215     if (found && type == object_free_type_) {
    216       // Found a free object. Change it to the proper type and return it. If
    217       // the type-change fails that means another thread has taken this from
    218       // under us so ignore it and keep trying.
    219       if (allocator_->ChangeType(found, object_type_, object_free_type_, false))
    220         return found;
    221     }
    222     if (found == last) {
    223       // Wrapped. No desired object was found.
    224       break;
    225     }
    226     if (!found) {
    227       // Reached end; start over at the beginning.
    228       iterator_.Reset();
    229     }
    230   }
    231 
    232   // No free block was found so instead allocate a new one.
    233   Reference allocated = allocator_->Allocate(object_size_, object_type_);
    234   if (allocated && make_iterable_)
    235     allocator_->MakeIterable(allocated);
    236   return allocated;
    237 }
    238 
    239 void ActivityTrackerMemoryAllocator::ReleaseObjectReference(Reference ref) {
    240   // Mark object as free.
    241   bool success = allocator_->ChangeType(ref, object_free_type_, object_type_,
    242                                         /*clear=*/true);
    243   DCHECK(success);
    244 
    245   // Add this reference to our "free" cache if there is space. If not, the type
    246   // has still been changed to indicate that it is free so this (or another)
    247   // thread can find it, albeit more slowly, using the iteration method above.
    248   if (cache_used_ < cache_size_)
    249     cache_values_[cache_used_++] = ref;
    250 }
    251 
    252 // static
    253 void Activity::FillFrom(Activity* activity,
    254                         const void* program_counter,
    255                         const void* origin,
    256                         Type type,
    257                         const ActivityData& data) {
    258   activity->time_internal = base::TimeTicks::Now().ToInternalValue();
    259   activity->calling_address = reinterpret_cast<uintptr_t>(program_counter);
    260   activity->origin_address = reinterpret_cast<uintptr_t>(origin);
    261   activity->activity_type = type;
    262   activity->data = data;
    263 
    264 #if (!defined(OS_NACL) && DCHECK_IS_ON()) || defined(ADDRESS_SANITIZER)
    265   // Create a stacktrace from the current location and get the addresses for
    266   // improved debuggability.
    267   StackTrace stack_trace;
    268   size_t stack_depth;
    269   const void* const* stack_addrs = stack_trace.Addresses(&stack_depth);
    270   // Copy the stack addresses, ignoring the first one (here).
    271   size_t i;
    272   for (i = 1; i < stack_depth && i < kActivityCallStackSize; ++i) {
    273     activity->call_stack[i - 1] = reinterpret_cast<uintptr_t>(stack_addrs[i]);
    274   }
    275   activity->call_stack[i - 1] = 0;
    276 #else
    277   activity->call_stack[0] = 0;
    278 #endif
    279 }
    280 
    281 ActivityUserData::TypedValue::TypedValue() = default;
    282 ActivityUserData::TypedValue::TypedValue(const TypedValue& other) = default;
    283 ActivityUserData::TypedValue::~TypedValue() = default;
    284 
    285 StringPiece ActivityUserData::TypedValue::Get() const {
    286   DCHECK_EQ(RAW_VALUE, type_);
    287   return long_value_;
    288 }
    289 
    290 StringPiece ActivityUserData::TypedValue::GetString() const {
    291   DCHECK_EQ(STRING_VALUE, type_);
    292   return long_value_;
    293 }
    294 
    295 bool ActivityUserData::TypedValue::GetBool() const {
    296   DCHECK_EQ(BOOL_VALUE, type_);
    297   return short_value_ != 0;
    298 }
    299 
    300 char ActivityUserData::TypedValue::GetChar() const {
    301   DCHECK_EQ(CHAR_VALUE, type_);
    302   return static_cast<char>(short_value_);
    303 }
    304 
    305 int64_t ActivityUserData::TypedValue::GetInt() const {
    306   DCHECK_EQ(SIGNED_VALUE, type_);
    307   return static_cast<int64_t>(short_value_);
    308 }
    309 
    310 uint64_t ActivityUserData::TypedValue::GetUint() const {
    311   DCHECK_EQ(UNSIGNED_VALUE, type_);
    312   return static_cast<uint64_t>(short_value_);
    313 }
    314 
    315 StringPiece ActivityUserData::TypedValue::GetReference() const {
    316   DCHECK_EQ(RAW_VALUE_REFERENCE, type_);
    317   return ref_value_;
    318 }
    319 
    320 StringPiece ActivityUserData::TypedValue::GetStringReference() const {
    321   DCHECK_EQ(STRING_VALUE_REFERENCE, type_);
    322   return ref_value_;
    323 }
    324 
    325 // These are required because std::atomic is (currently) not a POD type and
    326 // thus clang requires explicit out-of-line constructors and destructors even
    327 // when they do nothing.
    328 ActivityUserData::ValueInfo::ValueInfo() = default;
    329 ActivityUserData::ValueInfo::ValueInfo(ValueInfo&&) = default;
    330 ActivityUserData::ValueInfo::~ValueInfo() = default;
    331 ActivityUserData::MemoryHeader::MemoryHeader() = default;
    332 ActivityUserData::MemoryHeader::~MemoryHeader() = default;
    333 ActivityUserData::FieldHeader::FieldHeader() = default;
    334 ActivityUserData::FieldHeader::~FieldHeader() = default;
    335 
    336 ActivityUserData::ActivityUserData() : ActivityUserData(nullptr, 0, -1) {}
    337 
    338 ActivityUserData::ActivityUserData(void* memory, size_t size, int64_t pid)
    339     : memory_(reinterpret_cast<char*>(memory)),
    340       available_(RoundDownToAlignment(size, kMemoryAlignment)),
    341       header_(reinterpret_cast<MemoryHeader*>(memory)),
    342       orig_data_id(0),
    343       orig_process_id(0),
    344       orig_create_stamp(0) {
    345   // It's possible that no user data is being stored.
    346   if (!memory_)
    347     return;
    348 
    349   static_assert(0 == sizeof(MemoryHeader) % kMemoryAlignment, "invalid header");
    350   DCHECK_LT(sizeof(MemoryHeader), available_);
    351   if (header_->owner.data_id.load(std::memory_order_acquire) == 0)
    352     header_->owner.Release_Initialize(pid);
    353   memory_ += sizeof(MemoryHeader);
    354   available_ -= sizeof(MemoryHeader);
    355 
    356   // Make a copy of identifying information for later comparison.
    357   *const_cast<uint32_t*>(&orig_data_id) =
    358       header_->owner.data_id.load(std::memory_order_acquire);
    359   *const_cast<int64_t*>(&orig_process_id) = header_->owner.process_id;
    360   *const_cast<int64_t*>(&orig_create_stamp) = header_->owner.create_stamp;
    361 
    362   // If there is already data present, load that. This allows the same class
    363   // to be used for analysis through snapshots.
    364   ImportExistingData();
    365 }
    366 
    367 ActivityUserData::~ActivityUserData() = default;
    368 
    369 bool ActivityUserData::CreateSnapshot(Snapshot* output_snapshot) const {
    370   DCHECK(output_snapshot);
    371   DCHECK(output_snapshot->empty());
    372 
    373   // Find any new data that may have been added by an active instance of this
    374   // class that is adding records.
    375   ImportExistingData();
    376 
    377   // Add all the values to the snapshot.
    378   for (const auto& entry : values_) {
    379     TypedValue value;
    380     const size_t size = entry.second.size_ptr->load(std::memory_order_acquire);
    381     value.type_ = entry.second.type;
    382     DCHECK_GE(entry.second.extent, size);
    383 
    384     switch (entry.second.type) {
    385       case RAW_VALUE:
    386       case STRING_VALUE:
    387         value.long_value_ =
    388             std::string(reinterpret_cast<char*>(entry.second.memory), size);
    389         break;
    390       case RAW_VALUE_REFERENCE:
    391       case STRING_VALUE_REFERENCE: {
    392         ReferenceRecord* ref =
    393             reinterpret_cast<ReferenceRecord*>(entry.second.memory);
    394         value.ref_value_ = StringPiece(
    395             reinterpret_cast<char*>(static_cast<uintptr_t>(ref->address)),
    396             static_cast<size_t>(ref->size));
    397       } break;
    398       case BOOL_VALUE:
    399       case CHAR_VALUE:
    400         value.short_value_ = *reinterpret_cast<char*>(entry.second.memory);
    401         break;
    402       case SIGNED_VALUE:
    403       case UNSIGNED_VALUE:
    404         value.short_value_ = *reinterpret_cast<uint64_t*>(entry.second.memory);
    405         break;
    406       case END_OF_VALUES:  // Included for completeness purposes.
    407         NOTREACHED();
    408     }
    409     auto inserted = output_snapshot->insert(
    410         std::make_pair(entry.second.name.as_string(), std::move(value)));
    411     DCHECK(inserted.second);  // True if inserted, false if existed.
    412   }
    413 
    414   // Another import attempt will validate that the underlying memory has not
    415   // been reused for another purpose. Entries added since the first import
    416   // will be ignored here but will be returned if another snapshot is created.
    417   ImportExistingData();
    418   if (!memory_) {
    419     output_snapshot->clear();
    420     return false;
    421   }
    422 
    423   // Successful snapshot.
    424   return true;
    425 }
    426 
    427 const void* ActivityUserData::GetBaseAddress() const {
    428   // The |memory_| pointer advances as elements are written but the |header_|
    429   // value is always at the start of the block so just return that.
    430   return header_;
    431 }
    432 
    433 void ActivityUserData::SetOwningProcessIdForTesting(int64_t pid,
    434                                                     int64_t stamp) {
    435   if (!header_)
    436     return;
    437   header_->owner.SetOwningProcessIdForTesting(pid, stamp);
    438 }
    439 
    440 // static
    441 bool ActivityUserData::GetOwningProcessId(const void* memory,
    442                                           int64_t* out_id,
    443                                           int64_t* out_stamp) {
    444   const MemoryHeader* header = reinterpret_cast<const MemoryHeader*>(memory);
    445   return OwningProcess::GetOwningProcessId(&header->owner, out_id, out_stamp);
    446 }
    447 
    448 void ActivityUserData::Set(StringPiece name,
    449                            ValueType type,
    450                            const void* memory,
    451                            size_t size) {
    452   DCHECK_GE(std::numeric_limits<uint8_t>::max(), name.length());
    453   size = std::min(std::numeric_limits<uint16_t>::max() - (kMemoryAlignment - 1),
    454                   size);
    455 
    456   // It's possible that no user data is being stored.
    457   if (!memory_)
    458     return;
    459 
    460   // The storage of a name is limited so use that limit during lookup.
    461   if (name.length() > kMaxUserDataNameLength)
    462     name.set(name.data(), kMaxUserDataNameLength);
    463 
    464   ValueInfo* info;
    465   auto existing = values_.find(name);
    466   if (existing != values_.end()) {
    467     info = &existing->second;
    468   } else {
    469     // The name size is limited to what can be held in a single byte but
    470     // because there are not alignment constraints on strings, it's set tight
    471     // against the header. Its extent (the reserved space, even if it's not
    472     // all used) is calculated so that, when pressed against the header, the
    473     // following field will be aligned properly.
    474     size_t name_size = name.length();
    475     size_t name_extent =
    476         RoundUpToAlignment(sizeof(FieldHeader) + name_size, kMemoryAlignment) -
    477         sizeof(FieldHeader);
    478     size_t value_extent = RoundUpToAlignment(size, kMemoryAlignment);
    479 
    480     // The "base size" is the size of the header and (padded) string key. Stop
    481     // now if there's not room enough for even this.
    482     size_t base_size = sizeof(FieldHeader) + name_extent;
    483     if (base_size > available_)
    484       return;
    485 
    486     // The "full size" is the size for storing the entire value.
    487     size_t full_size = std::min(base_size + value_extent, available_);
    488 
    489     // If the value is actually a single byte, see if it can be stuffed at the
    490     // end of the name extent rather than wasting kMemoryAlignment bytes.
    491     if (size == 1 && name_extent > name_size) {
    492       full_size = base_size;
    493       --name_extent;
    494       --base_size;
    495     }
    496 
    497     // Truncate the stored size to the amount of available memory. Stop now if
    498     // there's not any room for even part of the value.
    499     if (size != 0) {
    500       size = std::min(full_size - base_size, size);
    501       if (size == 0)
    502         return;
    503     }
    504 
    505     // Allocate a chunk of memory.
    506     FieldHeader* header = reinterpret_cast<FieldHeader*>(memory_);
    507     memory_ += full_size;
    508     available_ -= full_size;
    509 
    510     // Datafill the header and name records. Memory must be zeroed. The |type|
    511     // is written last, atomically, to release all the other values.
    512     DCHECK_EQ(END_OF_VALUES, header->type.load(std::memory_order_relaxed));
    513     DCHECK_EQ(0, header->value_size.load(std::memory_order_relaxed));
    514     header->name_size = static_cast<uint8_t>(name_size);
    515     header->record_size = full_size;
    516     char* name_memory = reinterpret_cast<char*>(header) + sizeof(FieldHeader);
    517     void* value_memory =
    518         reinterpret_cast<char*>(header) + sizeof(FieldHeader) + name_extent;
    519     memcpy(name_memory, name.data(), name_size);
    520     header->type.store(type, std::memory_order_release);
    521 
    522     // Create an entry in |values_| so that this field can be found and changed
    523     // later on without having to allocate new entries.
    524     StringPiece persistent_name(name_memory, name_size);
    525     auto inserted =
    526         values_.insert(std::make_pair(persistent_name, ValueInfo()));
    527     DCHECK(inserted.second);  // True if inserted, false if existed.
    528     info = &inserted.first->second;
    529     info->name = persistent_name;
    530     info->memory = value_memory;
    531     info->size_ptr = &header->value_size;
    532     info->extent = full_size - sizeof(FieldHeader) - name_extent;
    533     info->type = type;
    534   }
    535 
    536   // Copy the value data to storage. The |size| is written last, atomically, to
    537   // release the copied data. Until then, a parallel reader will just ignore
    538   // records with a zero size.
    539   DCHECK_EQ(type, info->type);
    540   size = std::min(size, info->extent);
    541   info->size_ptr->store(0, std::memory_order_seq_cst);
    542   memcpy(info->memory, memory, size);
    543   info->size_ptr->store(size, std::memory_order_release);
    544 }
    545 
    546 void ActivityUserData::SetReference(StringPiece name,
    547                                     ValueType type,
    548                                     const void* memory,
    549                                     size_t size) {
    550   ReferenceRecord rec;
    551   rec.address = reinterpret_cast<uintptr_t>(memory);
    552   rec.size = size;
    553   Set(name, type, &rec, sizeof(rec));
    554 }
    555 
    556 void ActivityUserData::ImportExistingData() const {
    557   // It's possible that no user data is being stored.
    558   if (!memory_)
    559     return;
    560 
    561   while (available_ > sizeof(FieldHeader)) {
    562     FieldHeader* header = reinterpret_cast<FieldHeader*>(memory_);
    563     ValueType type =
    564         static_cast<ValueType>(header->type.load(std::memory_order_acquire));
    565     if (type == END_OF_VALUES)
    566       return;
    567     if (header->record_size > available_)
    568       return;
    569 
    570     size_t value_offset = RoundUpToAlignment(
    571         sizeof(FieldHeader) + header->name_size, kMemoryAlignment);
    572     if (header->record_size == value_offset &&
    573         header->value_size.load(std::memory_order_relaxed) == 1) {
    574       value_offset -= 1;
    575     }
    576     if (value_offset + header->value_size > header->record_size)
    577       return;
    578 
    579     ValueInfo info;
    580     info.name = StringPiece(memory_ + sizeof(FieldHeader), header->name_size);
    581     info.type = type;
    582     info.memory = memory_ + value_offset;
    583     info.size_ptr = &header->value_size;
    584     info.extent = header->record_size - value_offset;
    585 
    586     StringPiece key(info.name);
    587     values_.insert(std::make_pair(key, std::move(info)));
    588 
    589     memory_ += header->record_size;
    590     available_ -= header->record_size;
    591   }
    592 
    593   // Check if memory has been completely reused.
    594   if (header_->owner.data_id.load(std::memory_order_acquire) != orig_data_id ||
    595       header_->owner.process_id != orig_process_id ||
    596       header_->owner.create_stamp != orig_create_stamp) {
    597     memory_ = nullptr;
    598     values_.clear();
    599   }
    600 }
    601 
    602 // This information is kept for every thread that is tracked. It is filled
    603 // the very first time the thread is seen. All fields must be of exact sizes
    604 // so there is no issue moving between 32 and 64-bit builds.
    605 struct ThreadActivityTracker::Header {
    606   // Defined in .h for analyzer access. Increment this if structure changes!
    607   static constexpr uint32_t kPersistentTypeId =
    608       GlobalActivityTracker::kTypeIdActivityTracker;
    609 
    610   // Expected size for 32/64-bit check.
    611   static constexpr size_t kExpectedInstanceSize =
    612       OwningProcess::kExpectedInstanceSize + Activity::kExpectedInstanceSize +
    613       72;
    614 
    615   // This information uniquely identifies a process.
    616   OwningProcess owner;
    617 
    618   // The thread-id (thread_ref.as_id) to which this data belongs. This number
    619   // is not guaranteed to mean anything but combined with the process-id from
    620   // OwningProcess is unique among all active trackers.
    621   ThreadRef thread_ref;
    622 
    623   // The start-time and start-ticks when the data was created. Each activity
    624   // record has a |time_internal| value that can be converted to a "wall time"
    625   // with these two values.
    626   int64_t start_time;
    627   int64_t start_ticks;
    628 
    629   // The number of Activity slots (spaces that can hold an Activity) that
    630   // immediately follow this structure in memory.
    631   uint32_t stack_slots;
    632 
    633   // Some padding to keep everything 64-bit aligned.
    634   uint32_t padding;
    635 
    636   // The current depth of the stack. This may be greater than the number of
    637   // slots. If the depth exceeds the number of slots, the newest entries
    638   // won't be recorded.
    639   std::atomic<uint32_t> current_depth;
    640 
    641   // A memory location used to indicate if changes have been made to the data
    642   // that would invalidate an in-progress read of its contents. The active
    643   // tracker will increment the value whenever something gets popped from the
    644   // stack. A monitoring tracker can check the value before and after access
    645   // to know, if it's still the same, that the contents didn't change while
    646   // being copied.
    647   std::atomic<uint32_t> data_version;
    648 
    649   // The last "exception" activity. This can't be stored on the stack because
    650   // that could get popped as things unwind.
    651   Activity last_exception;
    652 
    653   // The name of the thread (up to a maximum length). Dynamic-length names
    654   // are not practical since the memory has to come from the same persistent
    655   // allocator that holds this structure and to which this object has no
    656   // reference.
    657   char thread_name[32];
    658 };
    659 
    660 ThreadActivityTracker::Snapshot::Snapshot() = default;
    661 ThreadActivityTracker::Snapshot::~Snapshot() = default;
    662 
    663 ThreadActivityTracker::ScopedActivity::ScopedActivity(
    664     ThreadActivityTracker* tracker,
    665     const void* program_counter,
    666     const void* origin,
    667     Activity::Type type,
    668     const ActivityData& data)
    669     : tracker_(tracker) {
    670   if (tracker_)
    671     activity_id_ = tracker_->PushActivity(program_counter, origin, type, data);
    672 }
    673 
    674 ThreadActivityTracker::ScopedActivity::~ScopedActivity() {
    675   if (tracker_)
    676     tracker_->PopActivity(activity_id_);
    677 }
    678 
    679 void ThreadActivityTracker::ScopedActivity::ChangeTypeAndData(
    680     Activity::Type type,
    681     const ActivityData& data) {
    682   if (tracker_)
    683     tracker_->ChangeActivity(activity_id_, type, data);
    684 }
    685 
    686 ThreadActivityTracker::ThreadActivityTracker(void* base, size_t size)
    687     : header_(static_cast<Header*>(base)),
    688       stack_(reinterpret_cast<Activity*>(reinterpret_cast<char*>(base) +
    689                                          sizeof(Header))),
    690 #if DCHECK_IS_ON()
    691       thread_id_(PlatformThreadRef()),
    692 #endif
    693       stack_slots_(
    694           static_cast<uint32_t>((size - sizeof(Header)) / sizeof(Activity))) {
    695 
    696   // Verify the parameters but fail gracefully if they're not valid so that
    697   // production code based on external inputs will not crash.  IsValid() will
    698   // return false in this case.
    699   if (!base ||
    700       // Ensure there is enough space for the header and at least a few records.
    701       size < sizeof(Header) + kMinStackDepth * sizeof(Activity) ||
    702       // Ensure that the |stack_slots_| calculation didn't overflow.
    703       (size - sizeof(Header)) / sizeof(Activity) >
    704           std::numeric_limits<uint32_t>::max()) {
    705     NOTREACHED();
    706     return;
    707   }
    708 
    709   // Ensure that the thread reference doesn't exceed the size of the ID number.
    710   // This won't compile at the global scope because Header is a private struct.
    711   static_assert(
    712       sizeof(header_->thread_ref) == sizeof(header_->thread_ref.as_id),
    713       "PlatformThreadHandle::Handle is too big to hold in 64-bit ID");
    714 
    715   // Ensure that the alignment of Activity.data is properly aligned to a
    716   // 64-bit boundary so there are no interoperability-issues across cpu
    717   // architectures.
    718   static_assert(offsetof(Activity, data) % sizeof(uint64_t) == 0,
    719                 "ActivityData.data is not 64-bit aligned");
    720 
    721   // Provided memory should either be completely initialized or all zeros.
    722   if (header_->owner.data_id.load(std::memory_order_relaxed) == 0) {
    723     // This is a new file. Double-check other fields and then initialize.
    724     DCHECK_EQ(0, header_->owner.process_id);
    725     DCHECK_EQ(0, header_->owner.create_stamp);
    726     DCHECK_EQ(0, header_->thread_ref.as_id);
    727     DCHECK_EQ(0, header_->start_time);
    728     DCHECK_EQ(0, header_->start_ticks);
    729     DCHECK_EQ(0U, header_->stack_slots);
    730     DCHECK_EQ(0U, header_->current_depth.load(std::memory_order_relaxed));
    731     DCHECK_EQ(0U, header_->data_version.load(std::memory_order_relaxed));
    732     DCHECK_EQ(0, stack_[0].time_internal);
    733     DCHECK_EQ(0U, stack_[0].origin_address);
    734     DCHECK_EQ(0U, stack_[0].call_stack[0]);
    735     DCHECK_EQ(0U, stack_[0].data.task.sequence_id);
    736 
    737 #if defined(OS_WIN)
    738     header_->thread_ref.as_tid = PlatformThread::CurrentId();
    739 #elif defined(OS_POSIX) || defined(OS_FUCHSIA)
    740     header_->thread_ref.as_handle =
    741         PlatformThread::CurrentHandle().platform_handle();
    742 #endif
    743 
    744     header_->start_time = base::Time::Now().ToInternalValue();
    745     header_->start_ticks = base::TimeTicks::Now().ToInternalValue();
    746     header_->stack_slots = stack_slots_;
    747     strlcpy(header_->thread_name, PlatformThread::GetName(),
    748             sizeof(header_->thread_name));
    749 
    750     // This is done last so as to guarantee that everything above is "released"
    751     // by the time this value gets written.
    752     header_->owner.Release_Initialize();
    753 
    754     valid_ = true;
    755     DCHECK(IsValid());
    756   } else {
    757     // This is a file with existing data. Perform basic consistency checks.
    758     valid_ = true;
    759     valid_ = IsValid();
    760   }
    761 }
    762 
    763 ThreadActivityTracker::~ThreadActivityTracker() = default;
    764 
    765 ThreadActivityTracker::ActivityId ThreadActivityTracker::PushActivity(
    766     const void* program_counter,
    767     const void* origin,
    768     Activity::Type type,
    769     const ActivityData& data) {
    770   // A thread-checker creates a lock to check the thread-id which means
    771   // re-entry into this code if lock acquisitions are being tracked.
    772   DCHECK(type == Activity::ACT_LOCK_ACQUIRE || CalledOnValidThread());
    773 
    774   // Get the current depth of the stack. No access to other memory guarded
    775   // by this variable is done here so a "relaxed" load is acceptable.
    776   uint32_t depth = header_->current_depth.load(std::memory_order_relaxed);
    777 
    778   // Handle the case where the stack depth has exceeded the storage capacity.
    779   // Extra entries will be lost leaving only the base of the stack.
    780   if (depth >= stack_slots_) {
    781     // Since no other threads modify the data, no compare/exchange is needed.
    782     // Since no other memory is being modified, a "relaxed" store is acceptable.
    783     header_->current_depth.store(depth + 1, std::memory_order_relaxed);
    784     return depth;
    785   }
    786 
    787   // Get a pointer to the next activity and load it. No atomicity is required
    788   // here because the memory is known only to this thread. It will be made
    789   // known to other threads once the depth is incremented.
    790   Activity::FillFrom(&stack_[depth], program_counter, origin, type, data);
    791 
    792   // Save the incremented depth. Because this guards |activity| memory filled
    793   // above that may be read by another thread once the recorded depth changes,
    794   // a "release" store is required.
    795   header_->current_depth.store(depth + 1, std::memory_order_release);
    796 
    797   // The current depth is used as the activity ID because it simply identifies
    798   // an entry. Once an entry is pop'd, it's okay to reuse the ID.
    799   return depth;
    800 }
    801 
    802 void ThreadActivityTracker::ChangeActivity(ActivityId id,
    803                                            Activity::Type type,
    804                                            const ActivityData& data) {
    805   DCHECK(CalledOnValidThread());
    806   DCHECK(type != Activity::ACT_NULL || &data != &kNullActivityData);
    807   DCHECK_LT(id, header_->current_depth.load(std::memory_order_acquire));
    808 
    809   // Update the information if it is being recorded (i.e. within slot limit).
    810   if (id < stack_slots_) {
    811     Activity* activity = &stack_[id];
    812 
    813     if (type != Activity::ACT_NULL) {
    814       DCHECK_EQ(activity->activity_type & Activity::ACT_CATEGORY_MASK,
    815                 type & Activity::ACT_CATEGORY_MASK);
    816       activity->activity_type = type;
    817     }
    818 
    819     if (&data != &kNullActivityData)
    820       activity->data = data;
    821   }
    822 }
    823 
    824 void ThreadActivityTracker::PopActivity(ActivityId id) {
    825   // Do an atomic decrement of the depth. No changes to stack entries guarded
    826   // by this variable are done here so a "relaxed" operation is acceptable.
    827   // |depth| will receive the value BEFORE it was modified which means the
    828   // return value must also be decremented. The slot will be "free" after
    829   // this call but since only a single thread can access this object, the
    830   // data will remain valid until this method returns or calls outside.
    831   uint32_t depth =
    832       header_->current_depth.fetch_sub(1, std::memory_order_relaxed) - 1;
    833 
    834   // Validate that everything is running correctly.
    835   DCHECK_EQ(id, depth);
    836 
    837   // A thread-checker creates a lock to check the thread-id which means
    838   // re-entry into this code if lock acquisitions are being tracked.
    839   DCHECK(stack_[depth].activity_type == Activity::ACT_LOCK_ACQUIRE ||
    840          CalledOnValidThread());
    841 
    842   // The stack has shrunk meaning that some other thread trying to copy the
    843   // contents for reporting purposes could get bad data. Increment the data
    844   // version so that it con tell that things have changed. This needs to
    845   // happen after the atomic |depth| operation above so a "release" store
    846   // is required.
    847   header_->data_version.fetch_add(1, std::memory_order_release);
    848 }
    849 
    850 std::unique_ptr<ActivityUserData> ThreadActivityTracker::GetUserData(
    851     ActivityId id,
    852     ActivityTrackerMemoryAllocator* allocator) {
    853   // Don't allow user data for lock acquisition as recursion may occur.
    854   if (stack_[id].activity_type == Activity::ACT_LOCK_ACQUIRE) {
    855     NOTREACHED();
    856     return std::make_unique<ActivityUserData>();
    857   }
    858 
    859   // User-data is only stored for activities actually held in the stack.
    860   if (id >= stack_slots_)
    861     return std::make_unique<ActivityUserData>();
    862 
    863   // Create and return a real UserData object.
    864   return CreateUserDataForActivity(&stack_[id], allocator);
    865 }
    866 
    867 bool ThreadActivityTracker::HasUserData(ActivityId id) {
    868   // User-data is only stored for activities actually held in the stack.
    869   return (id < stack_slots_ && stack_[id].user_data_ref);
    870 }
    871 
    872 void ThreadActivityTracker::ReleaseUserData(
    873     ActivityId id,
    874     ActivityTrackerMemoryAllocator* allocator) {
    875   // User-data is only stored for activities actually held in the stack.
    876   if (id < stack_slots_ && stack_[id].user_data_ref) {
    877     allocator->ReleaseObjectReference(stack_[id].user_data_ref);
    878     stack_[id].user_data_ref = 0;
    879   }
    880 }
    881 
    882 void ThreadActivityTracker::RecordExceptionActivity(const void* program_counter,
    883                                                     const void* origin,
    884                                                     Activity::Type type,
    885                                                     const ActivityData& data) {
    886   // A thread-checker creates a lock to check the thread-id which means
    887   // re-entry into this code if lock acquisitions are being tracked.
    888   DCHECK(CalledOnValidThread());
    889 
    890   // Fill the reusable exception activity.
    891   Activity::FillFrom(&header_->last_exception, program_counter, origin, type,
    892                      data);
    893 
    894   // The data has changed meaning that some other thread trying to copy the
    895   // contents for reporting purposes could get bad data.
    896   header_->data_version.fetch_add(1, std::memory_order_relaxed);
    897 }
    898 
    899 bool ThreadActivityTracker::IsValid() const {
    900   if (header_->owner.data_id.load(std::memory_order_acquire) == 0 ||
    901       header_->owner.process_id == 0 || header_->thread_ref.as_id == 0 ||
    902       header_->start_time == 0 || header_->start_ticks == 0 ||
    903       header_->stack_slots != stack_slots_ ||
    904       header_->thread_name[sizeof(header_->thread_name) - 1] != '\0') {
    905     return false;
    906   }
    907 
    908   return valid_;
    909 }
    910 
    911 bool ThreadActivityTracker::CreateSnapshot(Snapshot* output_snapshot) const {
    912   DCHECK(output_snapshot);
    913 
    914   // There is no "called on valid thread" check for this method as it can be
    915   // called from other threads or even other processes. It is also the reason
    916   // why atomic operations must be used in certain places above.
    917 
    918   // It's possible for the data to change while reading it in such a way that it
    919   // invalidates the read. Make several attempts but don't try forever.
    920   const int kMaxAttempts = 10;
    921   uint32_t depth;
    922 
    923   // Stop here if the data isn't valid.
    924   if (!IsValid())
    925     return false;
    926 
    927   // Allocate the maximum size for the stack so it doesn't have to be done
    928   // during the time-sensitive snapshot operation. It is shrunk once the
    929   // actual size is known.
    930   output_snapshot->activity_stack.reserve(stack_slots_);
    931 
    932   for (int attempt = 0; attempt < kMaxAttempts; ++attempt) {
    933     // Remember the data IDs to ensure nothing is replaced during the snapshot
    934     // operation. Use "acquire" so that all the non-atomic fields of the
    935     // structure are valid (at least at the current moment in time).
    936     const uint32_t starting_id =
    937         header_->owner.data_id.load(std::memory_order_acquire);
    938     const int64_t starting_create_stamp = header_->owner.create_stamp;
    939     const int64_t starting_process_id = header_->owner.process_id;
    940     const int64_t starting_thread_id = header_->thread_ref.as_id;
    941 
    942     // Note the current |data_version| so it's possible to detect at the end
    943     // that nothing has changed since copying the data began. A "cst" operation
    944     // is required to ensure it occurs before everything else. Using "cst"
    945     // memory ordering is relatively expensive but this is only done during
    946     // analysis so doesn't directly affect the worker threads.
    947     const uint32_t pre_version =
    948         header_->data_version.load(std::memory_order_seq_cst);
    949 
    950     // Fetching the current depth also "acquires" the contents of the stack.
    951     depth = header_->current_depth.load(std::memory_order_acquire);
    952     uint32_t count = std::min(depth, stack_slots_);
    953     output_snapshot->activity_stack.resize(count);
    954     if (count > 0) {
    955       // Copy the existing contents. Memcpy is used for speed.
    956       memcpy(&output_snapshot->activity_stack[0], stack_,
    957              count * sizeof(Activity));
    958     }
    959 
    960     // Capture the last exception.
    961     memcpy(&output_snapshot->last_exception, &header_->last_exception,
    962            sizeof(Activity));
    963 
    964     // TODO(bcwhite): Snapshot other things here.
    965 
    966     // Retry if something changed during the copy. A "cst" operation ensures
    967     // it must happen after all the above operations.
    968     if (header_->data_version.load(std::memory_order_seq_cst) != pre_version)
    969       continue;
    970 
    971     // Stack copied. Record it's full depth.
    972     output_snapshot->activity_stack_depth = depth;
    973 
    974     // Get the general thread information.
    975     output_snapshot->thread_name =
    976         std::string(header_->thread_name, sizeof(header_->thread_name) - 1);
    977     output_snapshot->create_stamp = header_->owner.create_stamp;
    978     output_snapshot->thread_id = header_->thread_ref.as_id;
    979     output_snapshot->process_id = header_->owner.process_id;
    980 
    981     // All characters of the thread-name buffer were copied so as to not break
    982     // if the trailing NUL were missing. Now limit the length if the actual
    983     // name is shorter.
    984     output_snapshot->thread_name.resize(
    985         strlen(output_snapshot->thread_name.c_str()));
    986 
    987     // If the data ID has changed then the tracker has exited and the memory
    988     // reused by a new one. Try again.
    989     if (header_->owner.data_id.load(std::memory_order_seq_cst) != starting_id ||
    990         output_snapshot->create_stamp != starting_create_stamp ||
    991         output_snapshot->process_id != starting_process_id ||
    992         output_snapshot->thread_id != starting_thread_id) {
    993       continue;
    994     }
    995 
    996     // Only successful if the data is still valid once everything is done since
    997     // it's possible for the thread to end somewhere in the middle and all its
    998     // values become garbage.
    999     if (!IsValid())
   1000       return false;
   1001 
   1002     // Change all the timestamps in the activities from "ticks" to "wall" time.
   1003     const Time start_time = Time::FromInternalValue(header_->start_time);
   1004     const int64_t start_ticks = header_->start_ticks;
   1005     for (Activity& activity : output_snapshot->activity_stack) {
   1006       activity.time_internal =
   1007           WallTimeFromTickTime(start_ticks, activity.time_internal, start_time)
   1008               .ToInternalValue();
   1009     }
   1010     output_snapshot->last_exception.time_internal =
   1011         WallTimeFromTickTime(start_ticks,
   1012                              output_snapshot->last_exception.time_internal,
   1013                              start_time)
   1014             .ToInternalValue();
   1015 
   1016     // Success!
   1017     return true;
   1018   }
   1019 
   1020   // Too many attempts.
   1021   return false;
   1022 }
   1023 
   1024 const void* ThreadActivityTracker::GetBaseAddress() {
   1025   return header_;
   1026 }
   1027 
   1028 uint32_t ThreadActivityTracker::GetDataVersionForTesting() {
   1029   return header_->data_version.load(std::memory_order_relaxed);
   1030 }
   1031 
   1032 void ThreadActivityTracker::SetOwningProcessIdForTesting(int64_t pid,
   1033                                                          int64_t stamp) {
   1034   header_->owner.SetOwningProcessIdForTesting(pid, stamp);
   1035 }
   1036 
   1037 // static
   1038 bool ThreadActivityTracker::GetOwningProcessId(const void* memory,
   1039                                                int64_t* out_id,
   1040                                                int64_t* out_stamp) {
   1041   const Header* header = reinterpret_cast<const Header*>(memory);
   1042   return OwningProcess::GetOwningProcessId(&header->owner, out_id, out_stamp);
   1043 }
   1044 
   1045 // static
   1046 size_t ThreadActivityTracker::SizeForStackDepth(int stack_depth) {
   1047   return static_cast<size_t>(stack_depth) * sizeof(Activity) + sizeof(Header);
   1048 }
   1049 
   1050 bool ThreadActivityTracker::CalledOnValidThread() {
   1051 #if DCHECK_IS_ON()
   1052   return thread_id_ == PlatformThreadRef();
   1053 #else
   1054   return true;
   1055 #endif
   1056 }
   1057 
   1058 std::unique_ptr<ActivityUserData>
   1059 ThreadActivityTracker::CreateUserDataForActivity(
   1060     Activity* activity,
   1061     ActivityTrackerMemoryAllocator* allocator) {
   1062   DCHECK_EQ(0U, activity->user_data_ref);
   1063 
   1064   PersistentMemoryAllocator::Reference ref = allocator->GetObjectReference();
   1065   void* memory = allocator->GetAsArray<char>(ref, kUserDataSize);
   1066   if (memory) {
   1067     std::unique_ptr<ActivityUserData> user_data =
   1068         std::make_unique<ActivityUserData>(memory, kUserDataSize);
   1069     activity->user_data_ref = ref;
   1070     activity->user_data_id = user_data->id();
   1071     return user_data;
   1072   }
   1073 
   1074   // Return a dummy object that will still accept (but ignore) Set() calls.
   1075   return std::make_unique<ActivityUserData>();
   1076 }
   1077 
   1078 // The instantiation of the GlobalActivityTracker object.
   1079 // The object held here will obviously not be destructed at process exit
   1080 // but that's best since PersistentMemoryAllocator objects (that underlie
   1081 // GlobalActivityTracker objects) are explicitly forbidden from doing anything
   1082 // essential at exit anyway due to the fact that they depend on data managed
   1083 // elsewhere and which could be destructed first. An AtomicWord is used instead
   1084 // of std::atomic because the latter can create global ctors and dtors.
   1085 subtle::AtomicWord GlobalActivityTracker::g_tracker_ = 0;
   1086 
   1087 GlobalActivityTracker::ModuleInfo::ModuleInfo() = default;
   1088 GlobalActivityTracker::ModuleInfo::ModuleInfo(ModuleInfo&& rhs) = default;
   1089 GlobalActivityTracker::ModuleInfo::ModuleInfo(const ModuleInfo& rhs) = default;
   1090 GlobalActivityTracker::ModuleInfo::~ModuleInfo() = default;
   1091 
   1092 GlobalActivityTracker::ModuleInfo& GlobalActivityTracker::ModuleInfo::operator=(
   1093     ModuleInfo&& rhs) = default;
   1094 GlobalActivityTracker::ModuleInfo& GlobalActivityTracker::ModuleInfo::operator=(
   1095     const ModuleInfo& rhs) = default;
   1096 
   1097 GlobalActivityTracker::ModuleInfoRecord::ModuleInfoRecord() = default;
   1098 GlobalActivityTracker::ModuleInfoRecord::~ModuleInfoRecord() = default;
   1099 
   1100 bool GlobalActivityTracker::ModuleInfoRecord::DecodeTo(
   1101     GlobalActivityTracker::ModuleInfo* info,
   1102     size_t record_size) const {
   1103   // Get the current "changes" indicator, acquiring all the other values.
   1104   uint32_t current_changes = changes.load(std::memory_order_acquire);
   1105 
   1106   // Copy out the dynamic information.
   1107   info->is_loaded = loaded != 0;
   1108   info->address = static_cast<uintptr_t>(address);
   1109   info->load_time = load_time;
   1110 
   1111   // Check to make sure no information changed while being read. A "seq-cst"
   1112   // operation is expensive but is only done during analysis and it's the only
   1113   // way to ensure this occurs after all the accesses above. If changes did
   1114   // occur then return a "not loaded" result so that |size| and |address|
   1115   // aren't expected to be accurate.
   1116   if ((current_changes & kModuleInformationChanging) != 0 ||
   1117       changes.load(std::memory_order_seq_cst) != current_changes) {
   1118     info->is_loaded = false;
   1119   }
   1120 
   1121   // Copy out the static information. These never change so don't have to be
   1122   // protected by the atomic |current_changes| operations.
   1123   info->size = static_cast<size_t>(size);
   1124   info->timestamp = timestamp;
   1125   info->age = age;
   1126   memcpy(info->identifier, identifier, sizeof(info->identifier));
   1127 
   1128   if (offsetof(ModuleInfoRecord, pickle) + pickle_size > record_size)
   1129     return false;
   1130   Pickle pickler(pickle, pickle_size);
   1131   PickleIterator iter(pickler);
   1132   return iter.ReadString(&info->file) && iter.ReadString(&info->debug_file);
   1133 }
   1134 
   1135 GlobalActivityTracker::ModuleInfoRecord*
   1136 GlobalActivityTracker::ModuleInfoRecord::CreateFrom(
   1137     const GlobalActivityTracker::ModuleInfo& info,
   1138     PersistentMemoryAllocator* allocator) {
   1139   Pickle pickler;
   1140   pickler.WriteString(info.file);
   1141   pickler.WriteString(info.debug_file);
   1142   size_t required_size = offsetof(ModuleInfoRecord, pickle) + pickler.size();
   1143   ModuleInfoRecord* record = allocator->New<ModuleInfoRecord>(required_size);
   1144   if (!record)
   1145     return nullptr;
   1146 
   1147   // These fields never changes and are done before the record is made
   1148   // iterable so no thread protection is necessary.
   1149   record->size = info.size;
   1150   record->timestamp = info.timestamp;
   1151   record->age = info.age;
   1152   memcpy(record->identifier, info.identifier, sizeof(identifier));
   1153   memcpy(record->pickle, pickler.data(), pickler.size());
   1154   record->pickle_size = pickler.size();
   1155   record->changes.store(0, std::memory_order_relaxed);
   1156 
   1157   // Initialize the owner info.
   1158   record->owner.Release_Initialize();
   1159 
   1160   // Now set those fields that can change.
   1161   bool success = record->UpdateFrom(info);
   1162   DCHECK(success);
   1163   return record;
   1164 }
   1165 
   1166 bool GlobalActivityTracker::ModuleInfoRecord::UpdateFrom(
   1167     const GlobalActivityTracker::ModuleInfo& info) {
   1168   // Updates can occur after the record is made visible so make changes atomic.
   1169   // A "strong" exchange ensures no false failures.
   1170   uint32_t old_changes = changes.load(std::memory_order_relaxed);
   1171   uint32_t new_changes = old_changes | kModuleInformationChanging;
   1172   if ((old_changes & kModuleInformationChanging) != 0 ||
   1173       !changes.compare_exchange_strong(old_changes, new_changes,
   1174                                        std::memory_order_acquire,
   1175                                        std::memory_order_acquire)) {
   1176     NOTREACHED() << "Multiple sources are updating module information.";
   1177     return false;
   1178   }
   1179 
   1180   loaded = info.is_loaded ? 1 : 0;
   1181   address = info.address;
   1182   load_time = Time::Now().ToInternalValue();
   1183 
   1184   bool success = changes.compare_exchange_strong(new_changes, old_changes + 1,
   1185                                                  std::memory_order_release,
   1186                                                  std::memory_order_relaxed);
   1187   DCHECK(success);
   1188   return true;
   1189 }
   1190 
   1191 GlobalActivityTracker::ScopedThreadActivity::ScopedThreadActivity(
   1192     const void* program_counter,
   1193     const void* origin,
   1194     Activity::Type type,
   1195     const ActivityData& data,
   1196     bool lock_allowed)
   1197     : ThreadActivityTracker::ScopedActivity(GetOrCreateTracker(lock_allowed),
   1198                                             program_counter,
   1199                                             origin,
   1200                                             type,
   1201                                             data) {}
   1202 
   1203 GlobalActivityTracker::ScopedThreadActivity::~ScopedThreadActivity() {
   1204   if (tracker_ && tracker_->HasUserData(activity_id_)) {
   1205     GlobalActivityTracker* global = GlobalActivityTracker::Get();
   1206     AutoLock lock(global->user_data_allocator_lock_);
   1207     tracker_->ReleaseUserData(activity_id_, &global->user_data_allocator_);
   1208   }
   1209 }
   1210 
   1211 ActivityUserData& GlobalActivityTracker::ScopedThreadActivity::user_data() {
   1212   if (!user_data_) {
   1213     if (tracker_) {
   1214       GlobalActivityTracker* global = GlobalActivityTracker::Get();
   1215       AutoLock lock(global->user_data_allocator_lock_);
   1216       user_data_ =
   1217           tracker_->GetUserData(activity_id_, &global->user_data_allocator_);
   1218     } else {
   1219       user_data_ = std::make_unique<ActivityUserData>();
   1220     }
   1221   }
   1222   return *user_data_;
   1223 }
   1224 
   1225 GlobalActivityTracker::ThreadSafeUserData::ThreadSafeUserData(void* memory,
   1226                                                               size_t size,
   1227                                                               int64_t pid)
   1228     : ActivityUserData(memory, size, pid) {}
   1229 
   1230 GlobalActivityTracker::ThreadSafeUserData::~ThreadSafeUserData() = default;
   1231 
   1232 void GlobalActivityTracker::ThreadSafeUserData::Set(StringPiece name,
   1233                                                     ValueType type,
   1234                                                     const void* memory,
   1235                                                     size_t size) {
   1236   AutoLock lock(data_lock_);
   1237   ActivityUserData::Set(name, type, memory, size);
   1238 }
   1239 
   1240 GlobalActivityTracker::ManagedActivityTracker::ManagedActivityTracker(
   1241     PersistentMemoryAllocator::Reference mem_reference,
   1242     void* base,
   1243     size_t size)
   1244     : ThreadActivityTracker(base, size),
   1245       mem_reference_(mem_reference),
   1246       mem_base_(base) {}
   1247 
   1248 GlobalActivityTracker::ManagedActivityTracker::~ManagedActivityTracker() {
   1249   // The global |g_tracker_| must point to the owner of this class since all
   1250   // objects of this type must be destructed before |g_tracker_| can be changed
   1251   // (something that only occurs in tests).
   1252   DCHECK(g_tracker_);
   1253   GlobalActivityTracker::Get()->ReturnTrackerMemory(this);
   1254 }
   1255 
   1256 void GlobalActivityTracker::CreateWithAllocator(
   1257     std::unique_ptr<PersistentMemoryAllocator> allocator,
   1258     int stack_depth,
   1259     int64_t process_id) {
   1260   // There's no need to do anything with the result. It is self-managing.
   1261   GlobalActivityTracker* global_tracker =
   1262       new GlobalActivityTracker(std::move(allocator), stack_depth, process_id);
   1263   // Create a tracker for this thread since it is known.
   1264   global_tracker->CreateTrackerForCurrentThread();
   1265 }
   1266 
   1267 #if !defined(OS_NACL)
   1268 // static
   1269 bool GlobalActivityTracker::CreateWithFile(const FilePath& file_path,
   1270                                            size_t size,
   1271                                            uint64_t id,
   1272                                            StringPiece name,
   1273                                            int stack_depth) {
   1274   DCHECK(!file_path.empty());
   1275   DCHECK_GE(static_cast<uint64_t>(std::numeric_limits<int64_t>::max()), size);
   1276 
   1277   // Create and map the file into memory and make it globally available.
   1278   std::unique_ptr<MemoryMappedFile> mapped_file(new MemoryMappedFile());
   1279   bool success = mapped_file->Initialize(
   1280       File(file_path, File::FLAG_CREATE_ALWAYS | File::FLAG_READ |
   1281                           File::FLAG_WRITE | File::FLAG_SHARE_DELETE),
   1282       {0, size}, MemoryMappedFile::READ_WRITE_EXTEND);
   1283   if (!success)
   1284     return false;
   1285   if (!FilePersistentMemoryAllocator::IsFileAcceptable(*mapped_file, false))
   1286     return false;
   1287   CreateWithAllocator(std::make_unique<FilePersistentMemoryAllocator>(
   1288                           std::move(mapped_file), size, id, name, false),
   1289                       stack_depth, 0);
   1290   return true;
   1291 }
   1292 #endif  // !defined(OS_NACL)
   1293 
   1294 // static
   1295 bool GlobalActivityTracker::CreateWithLocalMemory(size_t size,
   1296                                                   uint64_t id,
   1297                                                   StringPiece name,
   1298                                                   int stack_depth,
   1299                                                   int64_t process_id) {
   1300   CreateWithAllocator(
   1301       std::make_unique<LocalPersistentMemoryAllocator>(size, id, name),
   1302       stack_depth, process_id);
   1303   return true;
   1304 }
   1305 
   1306 // static
   1307 bool GlobalActivityTracker::CreateWithSharedMemory(
   1308     std::unique_ptr<SharedMemory> shm,
   1309     uint64_t id,
   1310     StringPiece name,
   1311     int stack_depth) {
   1312   if (shm->mapped_size() == 0 ||
   1313       !SharedPersistentMemoryAllocator::IsSharedMemoryAcceptable(*shm)) {
   1314     return false;
   1315   }
   1316   CreateWithAllocator(std::make_unique<SharedPersistentMemoryAllocator>(
   1317                           std::move(shm), id, name, false),
   1318                       stack_depth, 0);
   1319   return true;
   1320 }
   1321 
   1322 // static
   1323 bool GlobalActivityTracker::CreateWithSharedMemoryHandle(
   1324     const SharedMemoryHandle& handle,
   1325     size_t size,
   1326     uint64_t id,
   1327     StringPiece name,
   1328     int stack_depth) {
   1329   std::unique_ptr<SharedMemory> shm(
   1330       new SharedMemory(handle, /*readonly=*/false));
   1331   if (!shm->Map(size))
   1332     return false;
   1333   return CreateWithSharedMemory(std::move(shm), id, name, stack_depth);
   1334 }
   1335 
   1336 // static
   1337 void GlobalActivityTracker::SetForTesting(
   1338     std::unique_ptr<GlobalActivityTracker> tracker) {
   1339   CHECK(!subtle::NoBarrier_Load(&g_tracker_));
   1340   subtle::Release_Store(&g_tracker_,
   1341                         reinterpret_cast<uintptr_t>(tracker.release()));
   1342 }
   1343 
   1344 // static
   1345 std::unique_ptr<GlobalActivityTracker>
   1346 GlobalActivityTracker::ReleaseForTesting() {
   1347   GlobalActivityTracker* tracker = Get();
   1348   if (!tracker)
   1349     return nullptr;
   1350 
   1351   // Thread trackers assume that the global tracker is present for some
   1352   // operations so ensure that there aren't any.
   1353   tracker->ReleaseTrackerForCurrentThreadForTesting();
   1354   DCHECK_EQ(0, tracker->thread_tracker_count_.load(std::memory_order_relaxed));
   1355 
   1356   subtle::Release_Store(&g_tracker_, 0);
   1357   return WrapUnique(tracker);
   1358 }
   1359 
   1360 ThreadActivityTracker* GlobalActivityTracker::CreateTrackerForCurrentThread() {
   1361   DCHECK(!this_thread_tracker_.Get());
   1362 
   1363   PersistentMemoryAllocator::Reference mem_reference;
   1364 
   1365   {
   1366     base::AutoLock autolock(thread_tracker_allocator_lock_);
   1367     mem_reference = thread_tracker_allocator_.GetObjectReference();
   1368   }
   1369 
   1370   if (!mem_reference) {
   1371     // Failure. This shouldn't happen. But be graceful if it does, probably
   1372     // because the underlying allocator wasn't given enough memory to satisfy
   1373     // to all possible requests.
   1374     NOTREACHED();
   1375     // Report the thread-count at which the allocator was full so that the
   1376     // failure can be seen and underlying memory resized appropriately.
   1377     UMA_HISTOGRAM_COUNTS_1000(
   1378         "ActivityTracker.ThreadTrackers.MemLimitTrackerCount",
   1379         thread_tracker_count_.load(std::memory_order_relaxed));
   1380     // Return null, just as if tracking wasn't enabled.
   1381     return nullptr;
   1382   }
   1383 
   1384   // Convert the memory block found above into an actual memory address.
   1385   // Doing the conversion as a Header object enacts the 32/64-bit size
   1386   // consistency checks which would not otherwise be done. Unfortunately,
   1387   // some older compilers and MSVC don't have standard-conforming definitions
   1388   // of std::atomic which cause it not to be plain-old-data. Don't check on
   1389   // those platforms assuming that the checks on other platforms will be
   1390   // sufficient.
   1391   // TODO(bcwhite): Review this after major compiler releases.
   1392   DCHECK(mem_reference);
   1393   void* mem_base;
   1394   mem_base =
   1395       allocator_->GetAsObject<ThreadActivityTracker::Header>(mem_reference);
   1396 
   1397   DCHECK(mem_base);
   1398   DCHECK_LE(stack_memory_size_, allocator_->GetAllocSize(mem_reference));
   1399 
   1400   // Create a tracker with the acquired memory and set it as the tracker
   1401   // for this particular thread in thread-local-storage.
   1402   ManagedActivityTracker* tracker =
   1403       new ManagedActivityTracker(mem_reference, mem_base, stack_memory_size_);
   1404   DCHECK(tracker->IsValid());
   1405   this_thread_tracker_.Set(tracker);
   1406   int old_count = thread_tracker_count_.fetch_add(1, std::memory_order_relaxed);
   1407 
   1408   UMA_HISTOGRAM_EXACT_LINEAR("ActivityTracker.ThreadTrackers.Count",
   1409                              old_count + 1, static_cast<int>(kMaxThreadCount));
   1410   return tracker;
   1411 }
   1412 
   1413 void GlobalActivityTracker::ReleaseTrackerForCurrentThreadForTesting() {
   1414   ThreadActivityTracker* tracker =
   1415       reinterpret_cast<ThreadActivityTracker*>(this_thread_tracker_.Get());
   1416   if (tracker) {
   1417     this_thread_tracker_.Set(nullptr);
   1418     delete tracker;
   1419   }
   1420 }
   1421 
   1422 void GlobalActivityTracker::SetBackgroundTaskRunner(
   1423     const scoped_refptr<TaskRunner>& runner) {
   1424   AutoLock lock(global_tracker_lock_);
   1425   background_task_runner_ = runner;
   1426 }
   1427 
   1428 void GlobalActivityTracker::SetProcessExitCallback(
   1429     ProcessExitCallback callback) {
   1430   AutoLock lock(global_tracker_lock_);
   1431   process_exit_callback_ = callback;
   1432 }
   1433 
   1434 void GlobalActivityTracker::RecordProcessLaunch(
   1435     ProcessId process_id,
   1436     const FilePath::StringType& cmd) {
   1437   const int64_t pid = process_id;
   1438   DCHECK_NE(GetProcessId(), pid);
   1439   DCHECK_NE(0, pid);
   1440 
   1441   base::AutoLock lock(global_tracker_lock_);
   1442   if (base::ContainsKey(known_processes_, pid)) {
   1443     // TODO(bcwhite): Measure this in UMA.
   1444     NOTREACHED() << "Process #" << process_id
   1445                  << " was previously recorded as \"launched\""
   1446                  << " with no corresponding exit.\n"
   1447                  << known_processes_[pid];
   1448     known_processes_.erase(pid);
   1449   }
   1450 
   1451 #if defined(OS_WIN)
   1452   known_processes_.insert(std::make_pair(pid, UTF16ToUTF8(cmd)));
   1453 #else
   1454   known_processes_.insert(std::make_pair(pid, cmd));
   1455 #endif
   1456 }
   1457 
   1458 void GlobalActivityTracker::RecordProcessLaunch(
   1459     ProcessId process_id,
   1460     const FilePath::StringType& exe,
   1461     const FilePath::StringType& args) {
   1462   if (exe.find(FILE_PATH_LITERAL(" "))) {
   1463     RecordProcessLaunch(process_id,
   1464                         FilePath::StringType(FILE_PATH_LITERAL("\"")) + exe +
   1465                             FILE_PATH_LITERAL("\" ") + args);
   1466   } else {
   1467     RecordProcessLaunch(process_id, exe + FILE_PATH_LITERAL(' ') + args);
   1468   }
   1469 }
   1470 
   1471 void GlobalActivityTracker::RecordProcessExit(ProcessId process_id,
   1472                                               int exit_code) {
   1473   const int64_t pid = process_id;
   1474   DCHECK_NE(GetProcessId(), pid);
   1475   DCHECK_NE(0, pid);
   1476 
   1477   scoped_refptr<TaskRunner> task_runner;
   1478   std::string command_line;
   1479   {
   1480     base::AutoLock lock(global_tracker_lock_);
   1481     task_runner = background_task_runner_;
   1482     auto found = known_processes_.find(pid);
   1483     if (found != known_processes_.end()) {
   1484       command_line = std::move(found->second);
   1485       known_processes_.erase(found);
   1486     } else {
   1487       DLOG(ERROR) << "Recording exit of unknown process #" << process_id;
   1488     }
   1489   }
   1490 
   1491   // Use the current time to differentiate the process that just exited
   1492   // from any that might be created in the future with the same ID.
   1493   int64_t now_stamp = Time::Now().ToInternalValue();
   1494 
   1495   // The persistent allocator is thread-safe so run the iteration and
   1496   // adjustments on a worker thread if one was provided.
   1497   if (task_runner && !task_runner->RunsTasksInCurrentSequence()) {
   1498     task_runner->PostTask(
   1499         FROM_HERE,
   1500         BindOnce(&GlobalActivityTracker::CleanupAfterProcess, Unretained(this),
   1501                  pid, now_stamp, exit_code, std::move(command_line)));
   1502     return;
   1503   }
   1504 
   1505   CleanupAfterProcess(pid, now_stamp, exit_code, std::move(command_line));
   1506 }
   1507 
   1508 void GlobalActivityTracker::SetProcessPhase(ProcessPhase phase) {
   1509   process_data().SetInt(kProcessPhaseDataKey, phase);
   1510 }
   1511 
   1512 void GlobalActivityTracker::CleanupAfterProcess(int64_t process_id,
   1513                                                 int64_t exit_stamp,
   1514                                                 int exit_code,
   1515                                                 std::string&& command_line) {
   1516   // The process may not have exited cleanly so its necessary to go through
   1517   // all the data structures it may have allocated in the persistent memory
   1518   // segment and mark them as "released". This will allow them to be reused
   1519   // later on.
   1520 
   1521   PersistentMemoryAllocator::Iterator iter(allocator_.get());
   1522   PersistentMemoryAllocator::Reference ref;
   1523 
   1524   ProcessExitCallback process_exit_callback;
   1525   {
   1526     AutoLock lock(global_tracker_lock_);
   1527     process_exit_callback = process_exit_callback_;
   1528   }
   1529   if (process_exit_callback) {
   1530     // Find the processes user-data record so the process phase can be passed
   1531     // to the callback.
   1532     ActivityUserData::Snapshot process_data_snapshot;
   1533     while ((ref = iter.GetNextOfType(kTypeIdProcessDataRecord)) != 0) {
   1534       const void* memory = allocator_->GetAsArray<char>(
   1535           ref, kTypeIdProcessDataRecord, PersistentMemoryAllocator::kSizeAny);
   1536       if (!memory)
   1537         continue;
   1538       int64_t found_id;
   1539       int64_t create_stamp;
   1540       if (ActivityUserData::GetOwningProcessId(memory, &found_id,
   1541                                                &create_stamp)) {
   1542         if (found_id == process_id && create_stamp < exit_stamp) {
   1543           const ActivityUserData process_data(const_cast<void*>(memory),
   1544                                               allocator_->GetAllocSize(ref));
   1545           process_data.CreateSnapshot(&process_data_snapshot);
   1546           break;  // No need to look for any others.
   1547         }
   1548       }
   1549     }
   1550     iter.Reset();  // So it starts anew when used below.
   1551 
   1552     // Record the process's phase at exit so callback doesn't need to go
   1553     // searching based on a private key value.
   1554     ProcessPhase exit_phase = PROCESS_PHASE_UNKNOWN;
   1555     auto phase = process_data_snapshot.find(kProcessPhaseDataKey);
   1556     if (phase != process_data_snapshot.end())
   1557       exit_phase = static_cast<ProcessPhase>(phase->second.GetInt());
   1558 
   1559     // Perform the callback.
   1560     process_exit_callback.Run(process_id, exit_stamp, exit_code, exit_phase,
   1561                               std::move(command_line),
   1562                               std::move(process_data_snapshot));
   1563   }
   1564 
   1565   // Find all allocations associated with the exited process and free them.
   1566   uint32_t type;
   1567   while ((ref = iter.GetNext(&type)) != 0) {
   1568     switch (type) {
   1569       case kTypeIdActivityTracker:
   1570       case kTypeIdUserDataRecord:
   1571       case kTypeIdProcessDataRecord:
   1572       case ModuleInfoRecord::kPersistentTypeId: {
   1573         const void* memory = allocator_->GetAsArray<char>(
   1574             ref, type, PersistentMemoryAllocator::kSizeAny);
   1575         if (!memory)
   1576           continue;
   1577         int64_t found_id;
   1578         int64_t create_stamp;
   1579 
   1580         // By convention, the OwningProcess structure is always the first
   1581         // field of the structure so there's no need to handle all the
   1582         // cases separately.
   1583         if (OwningProcess::GetOwningProcessId(memory, &found_id,
   1584                                               &create_stamp)) {
   1585           // Only change the type to be "free" if the process ID matches and
   1586           // the creation time is before the exit time (so PID re-use doesn't
   1587           // cause the erasure of something that is in-use). Memory is cleared
   1588           // here, rather than when it's needed, so as to limit the impact at
   1589           // that critical time.
   1590           if (found_id == process_id && create_stamp < exit_stamp)
   1591             allocator_->ChangeType(ref, ~type, type, /*clear=*/true);
   1592         }
   1593       } break;
   1594     }
   1595   }
   1596 }
   1597 
   1598 void GlobalActivityTracker::RecordLogMessage(StringPiece message) {
   1599   // Allocate at least one extra byte so the string is NUL terminated. All
   1600   // memory returned by the allocator is guaranteed to be zeroed.
   1601   PersistentMemoryAllocator::Reference ref =
   1602       allocator_->Allocate(message.size() + 1, kTypeIdGlobalLogMessage);
   1603   char* memory = allocator_->GetAsArray<char>(ref, kTypeIdGlobalLogMessage,
   1604                                               message.size() + 1);
   1605   if (memory) {
   1606     memcpy(memory, message.data(), message.size());
   1607     allocator_->MakeIterable(ref);
   1608   }
   1609 }
   1610 
   1611 void GlobalActivityTracker::RecordModuleInfo(const ModuleInfo& info) {
   1612   AutoLock lock(modules_lock_);
   1613   auto found = modules_.find(info.file);
   1614   if (found != modules_.end()) {
   1615     ModuleInfoRecord* record = found->second;
   1616     DCHECK(record);
   1617 
   1618     // Update the basic state of module information that has been already
   1619     // recorded. It is assumed that the string information (identifier,
   1620     // version, etc.) remain unchanged which means that there's no need
   1621     // to create a new record to accommodate a possibly longer length.
   1622     record->UpdateFrom(info);
   1623     return;
   1624   }
   1625 
   1626   ModuleInfoRecord* record =
   1627       ModuleInfoRecord::CreateFrom(info, allocator_.get());
   1628   if (!record)
   1629     return;
   1630   allocator_->MakeIterable(record);
   1631   modules_.emplace(info.file, record);
   1632 }
   1633 
   1634 void GlobalActivityTracker::RecordFieldTrial(const std::string& trial_name,
   1635                                              StringPiece group_name) {
   1636   const std::string key = std::string("FieldTrial.") + trial_name;
   1637   process_data_.SetString(key, group_name);
   1638 }
   1639 
   1640 void GlobalActivityTracker::RecordException(const void* pc,
   1641                                             const void* origin,
   1642                                             uint32_t code) {
   1643   RecordExceptionImpl(pc, origin, code);
   1644 }
   1645 
   1646 void GlobalActivityTracker::MarkDeleted() {
   1647   allocator_->SetMemoryState(PersistentMemoryAllocator::MEMORY_DELETED);
   1648 }
   1649 
   1650 GlobalActivityTracker::GlobalActivityTracker(
   1651     std::unique_ptr<PersistentMemoryAllocator> allocator,
   1652     int stack_depth,
   1653     int64_t process_id)
   1654     : allocator_(std::move(allocator)),
   1655       stack_memory_size_(ThreadActivityTracker::SizeForStackDepth(stack_depth)),
   1656       process_id_(process_id == 0 ? GetCurrentProcId() : process_id),
   1657       this_thread_tracker_(&OnTLSDestroy),
   1658       thread_tracker_count_(0),
   1659       thread_tracker_allocator_(allocator_.get(),
   1660                                 kTypeIdActivityTracker,
   1661                                 kTypeIdActivityTrackerFree,
   1662                                 stack_memory_size_,
   1663                                 kCachedThreadMemories,
   1664                                 /*make_iterable=*/true),
   1665       user_data_allocator_(allocator_.get(),
   1666                            kTypeIdUserDataRecord,
   1667                            kTypeIdUserDataRecordFree,
   1668                            kUserDataSize,
   1669                            kCachedUserDataMemories,
   1670                            /*make_iterable=*/true),
   1671       process_data_(allocator_->GetAsArray<char>(
   1672                         AllocateFrom(allocator_.get(),
   1673                                      kTypeIdProcessDataRecordFree,
   1674                                      kProcessDataSize,
   1675                                      kTypeIdProcessDataRecord),
   1676                         kTypeIdProcessDataRecord,
   1677                         kProcessDataSize),
   1678                     kProcessDataSize,
   1679                     process_id_) {
   1680   DCHECK_NE(0, process_id_);
   1681 
   1682   // Ensure that there is no other global object and then make this one such.
   1683   DCHECK(!g_tracker_);
   1684   subtle::Release_Store(&g_tracker_, reinterpret_cast<uintptr_t>(this));
   1685 
   1686   // The data records must be iterable in order to be found by an analyzer.
   1687   allocator_->MakeIterable(allocator_->GetAsReference(
   1688       process_data_.GetBaseAddress(), kTypeIdProcessDataRecord));
   1689 
   1690   // Note that this process has launched.
   1691   SetProcessPhase(PROCESS_LAUNCHED);
   1692 
   1693   // Fetch and record all activated field trials.
   1694   FieldTrial::ActiveGroups active_groups;
   1695   FieldTrialList::GetActiveFieldTrialGroups(&active_groups);
   1696   for (auto& group : active_groups)
   1697     RecordFieldTrial(group.trial_name, group.group_name);
   1698 }
   1699 
   1700 GlobalActivityTracker::~GlobalActivityTracker() {
   1701   DCHECK(Get() == nullptr || Get() == this);
   1702   DCHECK_EQ(0, thread_tracker_count_.load(std::memory_order_relaxed));
   1703   subtle::Release_Store(&g_tracker_, 0);
   1704 }
   1705 
   1706 void GlobalActivityTracker::ReturnTrackerMemory(
   1707     ManagedActivityTracker* tracker) {
   1708   PersistentMemoryAllocator::Reference mem_reference = tracker->mem_reference_;
   1709   void* mem_base = tracker->mem_base_;
   1710   DCHECK(mem_reference);
   1711   DCHECK(mem_base);
   1712 
   1713   // Remove the destructed tracker from the set of known ones.
   1714   DCHECK_LE(1, thread_tracker_count_.load(std::memory_order_relaxed));
   1715   thread_tracker_count_.fetch_sub(1, std::memory_order_relaxed);
   1716 
   1717   // Release this memory for re-use at a later time.
   1718   base::AutoLock autolock(thread_tracker_allocator_lock_);
   1719   thread_tracker_allocator_.ReleaseObjectReference(mem_reference);
   1720 }
   1721 
   1722 void GlobalActivityTracker::RecordExceptionImpl(const void* pc,
   1723                                                 const void* origin,
   1724                                                 uint32_t code) {
   1725   // Get an existing tracker for this thread. It's not possible to create
   1726   // one at this point because such would involve memory allocations and
   1727   // other potentially complex operations that can cause failures if done
   1728   // within an exception handler. In most cases various operations will
   1729   // have already created the tracker so this shouldn't generally be a
   1730   // problem.
   1731   ThreadActivityTracker* tracker = GetTrackerForCurrentThread();
   1732   if (!tracker)
   1733     return;
   1734 
   1735   tracker->RecordExceptionActivity(pc, origin, Activity::ACT_EXCEPTION,
   1736                                    ActivityData::ForException(code));
   1737 }
   1738 
   1739 // static
   1740 void GlobalActivityTracker::OnTLSDestroy(void* value) {
   1741   delete reinterpret_cast<ManagedActivityTracker*>(value);
   1742 }
   1743 
   1744 ScopedActivity::ScopedActivity(const void* program_counter,
   1745                                uint8_t action,
   1746                                uint32_t id,
   1747                                int32_t info)
   1748     : GlobalActivityTracker::ScopedThreadActivity(
   1749           program_counter,
   1750           nullptr,
   1751           static_cast<Activity::Type>(Activity::ACT_GENERIC | action),
   1752           ActivityData::ForGeneric(id, info),
   1753           /*lock_allowed=*/true),
   1754       id_(id) {
   1755   // The action must not affect the category bits of the activity type.
   1756   DCHECK_EQ(0, action & Activity::ACT_CATEGORY_MASK);
   1757 }
   1758 
   1759 void ScopedActivity::ChangeAction(uint8_t action) {
   1760   DCHECK_EQ(0, action & Activity::ACT_CATEGORY_MASK);
   1761   ChangeTypeAndData(static_cast<Activity::Type>(Activity::ACT_GENERIC | action),
   1762                     kNullActivityData);
   1763 }
   1764 
   1765 void ScopedActivity::ChangeInfo(int32_t info) {
   1766   ChangeTypeAndData(Activity::ACT_NULL, ActivityData::ForGeneric(id_, info));
   1767 }
   1768 
   1769 void ScopedActivity::ChangeActionAndInfo(uint8_t action, int32_t info) {
   1770   DCHECK_EQ(0, action & Activity::ACT_CATEGORY_MASK);
   1771   ChangeTypeAndData(static_cast<Activity::Type>(Activity::ACT_GENERIC | action),
   1772                     ActivityData::ForGeneric(id_, info));
   1773 }
   1774 
   1775 ScopedTaskRunActivity::ScopedTaskRunActivity(
   1776     const void* program_counter,
   1777     const base::PendingTask& task)
   1778     : GlobalActivityTracker::ScopedThreadActivity(
   1779           program_counter,
   1780           task.posted_from.program_counter(),
   1781           Activity::ACT_TASK_RUN,
   1782           ActivityData::ForTask(task.sequence_num),
   1783           /*lock_allowed=*/true) {}
   1784 
   1785 ScopedLockAcquireActivity::ScopedLockAcquireActivity(
   1786     const void* program_counter,
   1787     const base::internal::LockImpl* lock)
   1788     : GlobalActivityTracker::ScopedThreadActivity(
   1789           program_counter,
   1790           nullptr,
   1791           Activity::ACT_LOCK_ACQUIRE,
   1792           ActivityData::ForLock(lock),
   1793           /*lock_allowed=*/false) {}
   1794 
   1795 ScopedEventWaitActivity::ScopedEventWaitActivity(
   1796     const void* program_counter,
   1797     const base::WaitableEvent* event)
   1798     : GlobalActivityTracker::ScopedThreadActivity(
   1799           program_counter,
   1800           nullptr,
   1801           Activity::ACT_EVENT_WAIT,
   1802           ActivityData::ForEvent(event),
   1803           /*lock_allowed=*/true) {}
   1804 
   1805 ScopedThreadJoinActivity::ScopedThreadJoinActivity(
   1806     const void* program_counter,
   1807     const base::PlatformThreadHandle* thread)
   1808     : GlobalActivityTracker::ScopedThreadActivity(
   1809           program_counter,
   1810           nullptr,
   1811           Activity::ACT_THREAD_JOIN,
   1812           ActivityData::ForThread(*thread),
   1813           /*lock_allowed=*/true) {}
   1814 
   1815 #if !defined(OS_NACL) && !defined(OS_IOS)
   1816 ScopedProcessWaitActivity::ScopedProcessWaitActivity(
   1817     const void* program_counter,
   1818     const base::Process* process)
   1819     : GlobalActivityTracker::ScopedThreadActivity(
   1820           program_counter,
   1821           nullptr,
   1822           Activity::ACT_PROCESS_WAIT,
   1823           ActivityData::ForProcess(process->Pid()),
   1824           /*lock_allowed=*/true) {}
   1825 #endif
   1826 
   1827 }  // namespace debug
   1828 }  // namespace base
   1829