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