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 <memory>
8*635a8641SAndroid Build Coastguard Worker
9*635a8641SAndroid Build Coastguard Worker #include "base/bind.h"
10*635a8641SAndroid Build Coastguard Worker #include "base/bind_helpers.h"
11*635a8641SAndroid Build Coastguard Worker #include "base/files/file.h"
12*635a8641SAndroid Build Coastguard Worker #include "base/files/file_util.h"
13*635a8641SAndroid Build Coastguard Worker #include "base/files/memory_mapped_file.h"
14*635a8641SAndroid Build Coastguard Worker #include "base/files/scoped_temp_dir.h"
15*635a8641SAndroid Build Coastguard Worker #include "base/memory/ptr_util.h"
16*635a8641SAndroid Build Coastguard Worker #include "base/pending_task.h"
17*635a8641SAndroid Build Coastguard Worker #include "base/rand_util.h"
18*635a8641SAndroid Build Coastguard Worker #include "base/synchronization/condition_variable.h"
19*635a8641SAndroid Build Coastguard Worker #include "base/synchronization/lock.h"
20*635a8641SAndroid Build Coastguard Worker #include "base/synchronization/spin_wait.h"
21*635a8641SAndroid Build Coastguard Worker #include "base/threading/platform_thread.h"
22*635a8641SAndroid Build Coastguard Worker #include "base/threading/simple_thread.h"
23*635a8641SAndroid Build Coastguard Worker #include "base/time/time.h"
24*635a8641SAndroid Build Coastguard Worker #include "testing/gtest/include/gtest/gtest.h"
25*635a8641SAndroid Build Coastguard Worker
26*635a8641SAndroid Build Coastguard Worker namespace base {
27*635a8641SAndroid Build Coastguard Worker namespace debug {
28*635a8641SAndroid Build Coastguard Worker
29*635a8641SAndroid Build Coastguard Worker namespace {
30*635a8641SAndroid Build Coastguard Worker
31*635a8641SAndroid Build Coastguard Worker class TestActivityTracker : public ThreadActivityTracker {
32*635a8641SAndroid Build Coastguard Worker public:
TestActivityTracker(std::unique_ptr<char[]> memory,size_t mem_size)33*635a8641SAndroid Build Coastguard Worker TestActivityTracker(std::unique_ptr<char[]> memory, size_t mem_size)
34*635a8641SAndroid Build Coastguard Worker : ThreadActivityTracker(memset(memory.get(), 0, mem_size), mem_size),
35*635a8641SAndroid Build Coastguard Worker mem_segment_(std::move(memory)) {}
36*635a8641SAndroid Build Coastguard Worker
37*635a8641SAndroid Build Coastguard Worker ~TestActivityTracker() override = default;
38*635a8641SAndroid Build Coastguard Worker
39*635a8641SAndroid Build Coastguard Worker private:
40*635a8641SAndroid Build Coastguard Worker std::unique_ptr<char[]> mem_segment_;
41*635a8641SAndroid Build Coastguard Worker };
42*635a8641SAndroid Build Coastguard Worker
43*635a8641SAndroid Build Coastguard Worker } // namespace
44*635a8641SAndroid Build Coastguard Worker
45*635a8641SAndroid Build Coastguard Worker
46*635a8641SAndroid Build Coastguard Worker class ActivityTrackerTest : public testing::Test {
47*635a8641SAndroid Build Coastguard Worker public:
48*635a8641SAndroid Build Coastguard Worker const int kMemorySize = 1 << 20; // 1MiB
49*635a8641SAndroid Build Coastguard Worker const int kStackSize = 1 << 10; // 1KiB
50*635a8641SAndroid Build Coastguard Worker
51*635a8641SAndroid Build Coastguard Worker using ActivityId = ThreadActivityTracker::ActivityId;
52*635a8641SAndroid Build Coastguard Worker
53*635a8641SAndroid Build Coastguard Worker ActivityTrackerTest() = default;
54*635a8641SAndroid Build Coastguard Worker
~ActivityTrackerTest()55*635a8641SAndroid Build Coastguard Worker ~ActivityTrackerTest() override {
56*635a8641SAndroid Build Coastguard Worker GlobalActivityTracker* global_tracker = GlobalActivityTracker::Get();
57*635a8641SAndroid Build Coastguard Worker if (global_tracker) {
58*635a8641SAndroid Build Coastguard Worker global_tracker->ReleaseTrackerForCurrentThreadForTesting();
59*635a8641SAndroid Build Coastguard Worker delete global_tracker;
60*635a8641SAndroid Build Coastguard Worker }
61*635a8641SAndroid Build Coastguard Worker }
62*635a8641SAndroid Build Coastguard Worker
CreateActivityTracker()63*635a8641SAndroid Build Coastguard Worker std::unique_ptr<ThreadActivityTracker> CreateActivityTracker() {
64*635a8641SAndroid Build Coastguard Worker std::unique_ptr<char[]> memory(new char[kStackSize]);
65*635a8641SAndroid Build Coastguard Worker return std::make_unique<TestActivityTracker>(std::move(memory), kStackSize);
66*635a8641SAndroid Build Coastguard Worker }
67*635a8641SAndroid Build Coastguard Worker
GetGlobalActiveTrackerCount()68*635a8641SAndroid Build Coastguard Worker size_t GetGlobalActiveTrackerCount() {
69*635a8641SAndroid Build Coastguard Worker GlobalActivityTracker* global_tracker = GlobalActivityTracker::Get();
70*635a8641SAndroid Build Coastguard Worker if (!global_tracker)
71*635a8641SAndroid Build Coastguard Worker return 0;
72*635a8641SAndroid Build Coastguard Worker return global_tracker->thread_tracker_count_.load(
73*635a8641SAndroid Build Coastguard Worker std::memory_order_relaxed);
74*635a8641SAndroid Build Coastguard Worker }
75*635a8641SAndroid Build Coastguard Worker
GetGlobalInactiveTrackerCount()76*635a8641SAndroid Build Coastguard Worker size_t GetGlobalInactiveTrackerCount() {
77*635a8641SAndroid Build Coastguard Worker GlobalActivityTracker* global_tracker = GlobalActivityTracker::Get();
78*635a8641SAndroid Build Coastguard Worker if (!global_tracker)
79*635a8641SAndroid Build Coastguard Worker return 0;
80*635a8641SAndroid Build Coastguard Worker AutoLock autolock(global_tracker->thread_tracker_allocator_lock_);
81*635a8641SAndroid Build Coastguard Worker return global_tracker->thread_tracker_allocator_.cache_used();
82*635a8641SAndroid Build Coastguard Worker }
83*635a8641SAndroid Build Coastguard Worker
GetGlobalUserDataMemoryCacheUsed()84*635a8641SAndroid Build Coastguard Worker size_t GetGlobalUserDataMemoryCacheUsed() {
85*635a8641SAndroid Build Coastguard Worker return GlobalActivityTracker::Get()->user_data_allocator_.cache_used();
86*635a8641SAndroid Build Coastguard Worker }
87*635a8641SAndroid Build Coastguard Worker
HandleProcessExit(int64_t id,int64_t stamp,int code,GlobalActivityTracker::ProcessPhase phase,std::string && command,ActivityUserData::Snapshot && data)88*635a8641SAndroid Build Coastguard Worker void HandleProcessExit(int64_t id,
89*635a8641SAndroid Build Coastguard Worker int64_t stamp,
90*635a8641SAndroid Build Coastguard Worker int code,
91*635a8641SAndroid Build Coastguard Worker GlobalActivityTracker::ProcessPhase phase,
92*635a8641SAndroid Build Coastguard Worker std::string&& command,
93*635a8641SAndroid Build Coastguard Worker ActivityUserData::Snapshot&& data) {
94*635a8641SAndroid Build Coastguard Worker exit_id_ = id;
95*635a8641SAndroid Build Coastguard Worker exit_stamp_ = stamp;
96*635a8641SAndroid Build Coastguard Worker exit_code_ = code;
97*635a8641SAndroid Build Coastguard Worker exit_phase_ = phase;
98*635a8641SAndroid Build Coastguard Worker exit_command_ = std::move(command);
99*635a8641SAndroid Build Coastguard Worker exit_data_ = std::move(data);
100*635a8641SAndroid Build Coastguard Worker }
101*635a8641SAndroid Build Coastguard Worker
102*635a8641SAndroid Build Coastguard Worker int64_t exit_id_ = 0;
103*635a8641SAndroid Build Coastguard Worker int64_t exit_stamp_;
104*635a8641SAndroid Build Coastguard Worker int exit_code_;
105*635a8641SAndroid Build Coastguard Worker GlobalActivityTracker::ProcessPhase exit_phase_;
106*635a8641SAndroid Build Coastguard Worker std::string exit_command_;
107*635a8641SAndroid Build Coastguard Worker ActivityUserData::Snapshot exit_data_;
108*635a8641SAndroid Build Coastguard Worker };
109*635a8641SAndroid Build Coastguard Worker
TEST_F(ActivityTrackerTest,UserDataTest)110*635a8641SAndroid Build Coastguard Worker TEST_F(ActivityTrackerTest, UserDataTest) {
111*635a8641SAndroid Build Coastguard Worker char buffer[256];
112*635a8641SAndroid Build Coastguard Worker memset(buffer, 0, sizeof(buffer));
113*635a8641SAndroid Build Coastguard Worker ActivityUserData data(buffer, sizeof(buffer));
114*635a8641SAndroid Build Coastguard Worker size_t space = sizeof(buffer) - sizeof(ActivityUserData::MemoryHeader);
115*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(space, data.available_);
116*635a8641SAndroid Build Coastguard Worker
117*635a8641SAndroid Build Coastguard Worker data.SetInt("foo", 1);
118*635a8641SAndroid Build Coastguard Worker space -= 24;
119*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(space, data.available_);
120*635a8641SAndroid Build Coastguard Worker
121*635a8641SAndroid Build Coastguard Worker data.SetUint("b", 1U); // Small names fit beside header in a word.
122*635a8641SAndroid Build Coastguard Worker space -= 16;
123*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(space, data.available_);
124*635a8641SAndroid Build Coastguard Worker
125*635a8641SAndroid Build Coastguard Worker data.Set("c", buffer, 10);
126*635a8641SAndroid Build Coastguard Worker space -= 24;
127*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(space, data.available_);
128*635a8641SAndroid Build Coastguard Worker
129*635a8641SAndroid Build Coastguard Worker data.SetString("dear john", "it's been fun");
130*635a8641SAndroid Build Coastguard Worker space -= 32;
131*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(space, data.available_);
132*635a8641SAndroid Build Coastguard Worker
133*635a8641SAndroid Build Coastguard Worker data.Set("c", buffer, 20);
134*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(space, data.available_);
135*635a8641SAndroid Build Coastguard Worker
136*635a8641SAndroid Build Coastguard Worker data.SetString("dear john", "but we're done together");
137*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(space, data.available_);
138*635a8641SAndroid Build Coastguard Worker
139*635a8641SAndroid Build Coastguard Worker data.SetString("dear john", "bye");
140*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(space, data.available_);
141*635a8641SAndroid Build Coastguard Worker
142*635a8641SAndroid Build Coastguard Worker data.SetChar("d", 'x');
143*635a8641SAndroid Build Coastguard Worker space -= 8;
144*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(space, data.available_);
145*635a8641SAndroid Build Coastguard Worker
146*635a8641SAndroid Build Coastguard Worker data.SetBool("ee", true);
147*635a8641SAndroid Build Coastguard Worker space -= 16;
148*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(space, data.available_);
149*635a8641SAndroid Build Coastguard Worker
150*635a8641SAndroid Build Coastguard Worker data.SetString("f", "");
151*635a8641SAndroid Build Coastguard Worker space -= 8;
152*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(space, data.available_);
153*635a8641SAndroid Build Coastguard Worker }
154*635a8641SAndroid Build Coastguard Worker
TEST_F(ActivityTrackerTest,PushPopTest)155*635a8641SAndroid Build Coastguard Worker TEST_F(ActivityTrackerTest, PushPopTest) {
156*635a8641SAndroid Build Coastguard Worker std::unique_ptr<ThreadActivityTracker> tracker = CreateActivityTracker();
157*635a8641SAndroid Build Coastguard Worker ThreadActivityTracker::Snapshot snapshot;
158*635a8641SAndroid Build Coastguard Worker
159*635a8641SAndroid Build Coastguard Worker ASSERT_TRUE(tracker->CreateSnapshot(&snapshot));
160*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(0U, snapshot.activity_stack_depth);
161*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(0U, snapshot.activity_stack.size());
162*635a8641SAndroid Build Coastguard Worker
163*635a8641SAndroid Build Coastguard Worker char origin1;
164*635a8641SAndroid Build Coastguard Worker ActivityId id1 = tracker->PushActivity(&origin1, Activity::ACT_TASK,
165*635a8641SAndroid Build Coastguard Worker ActivityData::ForTask(11));
166*635a8641SAndroid Build Coastguard Worker ASSERT_TRUE(tracker->CreateSnapshot(&snapshot));
167*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(1U, snapshot.activity_stack_depth);
168*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(1U, snapshot.activity_stack.size());
169*635a8641SAndroid Build Coastguard Worker EXPECT_NE(0, snapshot.activity_stack[0].time_internal);
170*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(Activity::ACT_TASK, snapshot.activity_stack[0].activity_type);
171*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(reinterpret_cast<uintptr_t>(&origin1),
172*635a8641SAndroid Build Coastguard Worker snapshot.activity_stack[0].origin_address);
173*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(11U, snapshot.activity_stack[0].data.task.sequence_id);
174*635a8641SAndroid Build Coastguard Worker
175*635a8641SAndroid Build Coastguard Worker char origin2;
176*635a8641SAndroid Build Coastguard Worker char lock2;
177*635a8641SAndroid Build Coastguard Worker ActivityId id2 = tracker->PushActivity(&origin2, Activity::ACT_LOCK,
178*635a8641SAndroid Build Coastguard Worker ActivityData::ForLock(&lock2));
179*635a8641SAndroid Build Coastguard Worker ASSERT_TRUE(tracker->CreateSnapshot(&snapshot));
180*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(2U, snapshot.activity_stack_depth);
181*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(2U, snapshot.activity_stack.size());
182*635a8641SAndroid Build Coastguard Worker EXPECT_LE(snapshot.activity_stack[0].time_internal,
183*635a8641SAndroid Build Coastguard Worker snapshot.activity_stack[1].time_internal);
184*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(Activity::ACT_LOCK, snapshot.activity_stack[1].activity_type);
185*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(reinterpret_cast<uintptr_t>(&origin2),
186*635a8641SAndroid Build Coastguard Worker snapshot.activity_stack[1].origin_address);
187*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(reinterpret_cast<uintptr_t>(&lock2),
188*635a8641SAndroid Build Coastguard Worker snapshot.activity_stack[1].data.lock.lock_address);
189*635a8641SAndroid Build Coastguard Worker
190*635a8641SAndroid Build Coastguard Worker tracker->PopActivity(id2);
191*635a8641SAndroid Build Coastguard Worker ASSERT_TRUE(tracker->CreateSnapshot(&snapshot));
192*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(1U, snapshot.activity_stack_depth);
193*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(1U, snapshot.activity_stack.size());
194*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(Activity::ACT_TASK, snapshot.activity_stack[0].activity_type);
195*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(reinterpret_cast<uintptr_t>(&origin1),
196*635a8641SAndroid Build Coastguard Worker snapshot.activity_stack[0].origin_address);
197*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(11U, snapshot.activity_stack[0].data.task.sequence_id);
198*635a8641SAndroid Build Coastguard Worker
199*635a8641SAndroid Build Coastguard Worker tracker->PopActivity(id1);
200*635a8641SAndroid Build Coastguard Worker ASSERT_TRUE(tracker->CreateSnapshot(&snapshot));
201*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(0U, snapshot.activity_stack_depth);
202*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(0U, snapshot.activity_stack.size());
203*635a8641SAndroid Build Coastguard Worker }
204*635a8641SAndroid Build Coastguard Worker
TEST_F(ActivityTrackerTest,ScopedTaskTest)205*635a8641SAndroid Build Coastguard Worker TEST_F(ActivityTrackerTest, ScopedTaskTest) {
206*635a8641SAndroid Build Coastguard Worker GlobalActivityTracker::CreateWithLocalMemory(kMemorySize, 0, "", 3, 0);
207*635a8641SAndroid Build Coastguard Worker
208*635a8641SAndroid Build Coastguard Worker ThreadActivityTracker* tracker =
209*635a8641SAndroid Build Coastguard Worker GlobalActivityTracker::Get()->GetOrCreateTrackerForCurrentThread();
210*635a8641SAndroid Build Coastguard Worker ThreadActivityTracker::Snapshot snapshot;
211*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(0U, GetGlobalUserDataMemoryCacheUsed());
212*635a8641SAndroid Build Coastguard Worker
213*635a8641SAndroid Build Coastguard Worker ASSERT_TRUE(tracker->CreateSnapshot(&snapshot));
214*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(0U, snapshot.activity_stack_depth);
215*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(0U, snapshot.activity_stack.size());
216*635a8641SAndroid Build Coastguard Worker
217*635a8641SAndroid Build Coastguard Worker {
218*635a8641SAndroid Build Coastguard Worker PendingTask task1(FROM_HERE, DoNothing());
219*635a8641SAndroid Build Coastguard Worker ScopedTaskRunActivity activity1(task1);
220*635a8641SAndroid Build Coastguard Worker ActivityUserData& user_data1 = activity1.user_data();
221*635a8641SAndroid Build Coastguard Worker (void)user_data1; // Tell compiler it's been used.
222*635a8641SAndroid Build Coastguard Worker
223*635a8641SAndroid Build Coastguard Worker ASSERT_TRUE(tracker->CreateSnapshot(&snapshot));
224*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(1U, snapshot.activity_stack_depth);
225*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(1U, snapshot.activity_stack.size());
226*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(Activity::ACT_TASK, snapshot.activity_stack[0].activity_type);
227*635a8641SAndroid Build Coastguard Worker
228*635a8641SAndroid Build Coastguard Worker {
229*635a8641SAndroid Build Coastguard Worker PendingTask task2(FROM_HERE, DoNothing());
230*635a8641SAndroid Build Coastguard Worker ScopedTaskRunActivity activity2(task2);
231*635a8641SAndroid Build Coastguard Worker ActivityUserData& user_data2 = activity2.user_data();
232*635a8641SAndroid Build Coastguard Worker (void)user_data2; // Tell compiler it's been used.
233*635a8641SAndroid Build Coastguard Worker
234*635a8641SAndroid Build Coastguard Worker ASSERT_TRUE(tracker->CreateSnapshot(&snapshot));
235*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(2U, snapshot.activity_stack_depth);
236*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(2U, snapshot.activity_stack.size());
237*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(Activity::ACT_TASK, snapshot.activity_stack[1].activity_type);
238*635a8641SAndroid Build Coastguard Worker }
239*635a8641SAndroid Build Coastguard Worker
240*635a8641SAndroid Build Coastguard Worker ASSERT_TRUE(tracker->CreateSnapshot(&snapshot));
241*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(1U, snapshot.activity_stack_depth);
242*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(1U, snapshot.activity_stack.size());
243*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(Activity::ACT_TASK, snapshot.activity_stack[0].activity_type);
244*635a8641SAndroid Build Coastguard Worker }
245*635a8641SAndroid Build Coastguard Worker
246*635a8641SAndroid Build Coastguard Worker ASSERT_TRUE(tracker->CreateSnapshot(&snapshot));
247*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(0U, snapshot.activity_stack_depth);
248*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(0U, snapshot.activity_stack.size());
249*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(2U, GetGlobalUserDataMemoryCacheUsed());
250*635a8641SAndroid Build Coastguard Worker }
251*635a8641SAndroid Build Coastguard Worker
252*635a8641SAndroid Build Coastguard Worker namespace {
253*635a8641SAndroid Build Coastguard Worker
254*635a8641SAndroid Build Coastguard Worker class SimpleLockThread : public SimpleThread {
255*635a8641SAndroid Build Coastguard Worker public:
SimpleLockThread(const std::string & name,Lock * lock)256*635a8641SAndroid Build Coastguard Worker SimpleLockThread(const std::string& name, Lock* lock)
257*635a8641SAndroid Build Coastguard Worker : SimpleThread(name, Options()),
258*635a8641SAndroid Build Coastguard Worker lock_(lock),
259*635a8641SAndroid Build Coastguard Worker data_changed_(false),
260*635a8641SAndroid Build Coastguard Worker is_running_(false) {}
261*635a8641SAndroid Build Coastguard Worker
262*635a8641SAndroid Build Coastguard Worker ~SimpleLockThread() override = default;
263*635a8641SAndroid Build Coastguard Worker
Run()264*635a8641SAndroid Build Coastguard Worker void Run() override {
265*635a8641SAndroid Build Coastguard Worker ThreadActivityTracker* tracker =
266*635a8641SAndroid Build Coastguard Worker GlobalActivityTracker::Get()->GetOrCreateTrackerForCurrentThread();
267*635a8641SAndroid Build Coastguard Worker uint32_t pre_version = tracker->GetDataVersionForTesting();
268*635a8641SAndroid Build Coastguard Worker
269*635a8641SAndroid Build Coastguard Worker is_running_.store(true, std::memory_order_relaxed);
270*635a8641SAndroid Build Coastguard Worker lock_->Acquire();
271*635a8641SAndroid Build Coastguard Worker data_changed_ = tracker->GetDataVersionForTesting() != pre_version;
272*635a8641SAndroid Build Coastguard Worker lock_->Release();
273*635a8641SAndroid Build Coastguard Worker is_running_.store(false, std::memory_order_relaxed);
274*635a8641SAndroid Build Coastguard Worker }
275*635a8641SAndroid Build Coastguard Worker
IsRunning()276*635a8641SAndroid Build Coastguard Worker bool IsRunning() { return is_running_.load(std::memory_order_relaxed); }
277*635a8641SAndroid Build Coastguard Worker
WasDataChanged()278*635a8641SAndroid Build Coastguard Worker bool WasDataChanged() { return data_changed_; };
279*635a8641SAndroid Build Coastguard Worker
280*635a8641SAndroid Build Coastguard Worker private:
281*635a8641SAndroid Build Coastguard Worker Lock* lock_;
282*635a8641SAndroid Build Coastguard Worker bool data_changed_;
283*635a8641SAndroid Build Coastguard Worker std::atomic<bool> is_running_;
284*635a8641SAndroid Build Coastguard Worker
285*635a8641SAndroid Build Coastguard Worker DISALLOW_COPY_AND_ASSIGN(SimpleLockThread);
286*635a8641SAndroid Build Coastguard Worker };
287*635a8641SAndroid Build Coastguard Worker
288*635a8641SAndroid Build Coastguard Worker } // namespace
289*635a8641SAndroid Build Coastguard Worker
TEST_F(ActivityTrackerTest,LockTest)290*635a8641SAndroid Build Coastguard Worker TEST_F(ActivityTrackerTest, LockTest) {
291*635a8641SAndroid Build Coastguard Worker GlobalActivityTracker::CreateWithLocalMemory(kMemorySize, 0, "", 3, 0);
292*635a8641SAndroid Build Coastguard Worker
293*635a8641SAndroid Build Coastguard Worker ThreadActivityTracker* tracker =
294*635a8641SAndroid Build Coastguard Worker GlobalActivityTracker::Get()->GetOrCreateTrackerForCurrentThread();
295*635a8641SAndroid Build Coastguard Worker ThreadActivityTracker::Snapshot snapshot;
296*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(0U, GetGlobalUserDataMemoryCacheUsed());
297*635a8641SAndroid Build Coastguard Worker
298*635a8641SAndroid Build Coastguard Worker Lock lock;
299*635a8641SAndroid Build Coastguard Worker uint32_t pre_version = tracker->GetDataVersionForTesting();
300*635a8641SAndroid Build Coastguard Worker
301*635a8641SAndroid Build Coastguard Worker // Check no activity when only "trying" a lock.
302*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(lock.Try());
303*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(pre_version, tracker->GetDataVersionForTesting());
304*635a8641SAndroid Build Coastguard Worker lock.Release();
305*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(pre_version, tracker->GetDataVersionForTesting());
306*635a8641SAndroid Build Coastguard Worker
307*635a8641SAndroid Build Coastguard Worker // Check no activity when acquiring a free lock.
308*635a8641SAndroid Build Coastguard Worker SimpleLockThread t1("locker1", &lock);
309*635a8641SAndroid Build Coastguard Worker t1.Start();
310*635a8641SAndroid Build Coastguard Worker t1.Join();
311*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(t1.WasDataChanged());
312*635a8641SAndroid Build Coastguard Worker
313*635a8641SAndroid Build Coastguard Worker // Check that activity is recorded when acquring a busy lock.
314*635a8641SAndroid Build Coastguard Worker SimpleLockThread t2("locker2", &lock);
315*635a8641SAndroid Build Coastguard Worker lock.Acquire();
316*635a8641SAndroid Build Coastguard Worker t2.Start();
317*635a8641SAndroid Build Coastguard Worker while (!t2.IsRunning())
318*635a8641SAndroid Build Coastguard Worker PlatformThread::Sleep(TimeDelta::FromMilliseconds(10));
319*635a8641SAndroid Build Coastguard Worker // t2 can't join until the lock is released but have to give time for t2 to
320*635a8641SAndroid Build Coastguard Worker // actually block on the lock before releasing it or the results will not
321*635a8641SAndroid Build Coastguard Worker // be correct.
322*635a8641SAndroid Build Coastguard Worker PlatformThread::Sleep(TimeDelta::FromMilliseconds(200));
323*635a8641SAndroid Build Coastguard Worker lock.Release();
324*635a8641SAndroid Build Coastguard Worker // Now the results will be valid.
325*635a8641SAndroid Build Coastguard Worker t2.Join();
326*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(t2.WasDataChanged());
327*635a8641SAndroid Build Coastguard Worker }
328*635a8641SAndroid Build Coastguard Worker
TEST_F(ActivityTrackerTest,ExceptionTest)329*635a8641SAndroid Build Coastguard Worker TEST_F(ActivityTrackerTest, ExceptionTest) {
330*635a8641SAndroid Build Coastguard Worker GlobalActivityTracker::CreateWithLocalMemory(kMemorySize, 0, "", 3, 0);
331*635a8641SAndroid Build Coastguard Worker GlobalActivityTracker* global = GlobalActivityTracker::Get();
332*635a8641SAndroid Build Coastguard Worker
333*635a8641SAndroid Build Coastguard Worker ThreadActivityTracker* tracker =
334*635a8641SAndroid Build Coastguard Worker GlobalActivityTracker::Get()->GetOrCreateTrackerForCurrentThread();
335*635a8641SAndroid Build Coastguard Worker ThreadActivityTracker::Snapshot snapshot;
336*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(0U, GetGlobalUserDataMemoryCacheUsed());
337*635a8641SAndroid Build Coastguard Worker
338*635a8641SAndroid Build Coastguard Worker ASSERT_TRUE(tracker->CreateSnapshot(&snapshot));
339*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(0U, snapshot.last_exception.activity_type);
340*635a8641SAndroid Build Coastguard Worker
341*635a8641SAndroid Build Coastguard Worker char origin;
342*635a8641SAndroid Build Coastguard Worker global->RecordException(&origin, 42);
343*635a8641SAndroid Build Coastguard Worker
344*635a8641SAndroid Build Coastguard Worker ASSERT_TRUE(tracker->CreateSnapshot(&snapshot));
345*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(Activity::ACT_EXCEPTION, snapshot.last_exception.activity_type);
346*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(reinterpret_cast<uintptr_t>(&origin),
347*635a8641SAndroid Build Coastguard Worker snapshot.last_exception.origin_address);
348*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(42U, snapshot.last_exception.data.exception.code);
349*635a8641SAndroid Build Coastguard Worker }
350*635a8641SAndroid Build Coastguard Worker
TEST_F(ActivityTrackerTest,CreateWithFileTest)351*635a8641SAndroid Build Coastguard Worker TEST_F(ActivityTrackerTest, CreateWithFileTest) {
352*635a8641SAndroid Build Coastguard Worker const char temp_name[] = "CreateWithFileTest";
353*635a8641SAndroid Build Coastguard Worker ScopedTempDir temp_dir;
354*635a8641SAndroid Build Coastguard Worker ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
355*635a8641SAndroid Build Coastguard Worker FilePath temp_file = temp_dir.GetPath().AppendASCII(temp_name);
356*635a8641SAndroid Build Coastguard Worker const size_t temp_size = 64 << 10; // 64 KiB
357*635a8641SAndroid Build Coastguard Worker
358*635a8641SAndroid Build Coastguard Worker // Create a global tracker on a new file.
359*635a8641SAndroid Build Coastguard Worker ASSERT_FALSE(PathExists(temp_file));
360*635a8641SAndroid Build Coastguard Worker GlobalActivityTracker::CreateWithFile(temp_file, temp_size, 0, "foo", 3);
361*635a8641SAndroid Build Coastguard Worker GlobalActivityTracker* global = GlobalActivityTracker::Get();
362*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(std::string("foo"), global->allocator()->Name());
363*635a8641SAndroid Build Coastguard Worker global->ReleaseTrackerForCurrentThreadForTesting();
364*635a8641SAndroid Build Coastguard Worker delete global;
365*635a8641SAndroid Build Coastguard Worker
366*635a8641SAndroid Build Coastguard Worker // Create a global tracker over an existing file, replacing it. If the
367*635a8641SAndroid Build Coastguard Worker // replacement doesn't work, the name will remain as it was first created.
368*635a8641SAndroid Build Coastguard Worker ASSERT_TRUE(PathExists(temp_file));
369*635a8641SAndroid Build Coastguard Worker GlobalActivityTracker::CreateWithFile(temp_file, temp_size, 0, "bar", 3);
370*635a8641SAndroid Build Coastguard Worker global = GlobalActivityTracker::Get();
371*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(std::string("bar"), global->allocator()->Name());
372*635a8641SAndroid Build Coastguard Worker global->ReleaseTrackerForCurrentThreadForTesting();
373*635a8641SAndroid Build Coastguard Worker delete global;
374*635a8641SAndroid Build Coastguard Worker }
375*635a8641SAndroid Build Coastguard Worker
376*635a8641SAndroid Build Coastguard Worker
377*635a8641SAndroid Build Coastguard Worker // GlobalActivityTracker tests below.
378*635a8641SAndroid Build Coastguard Worker
TEST_F(ActivityTrackerTest,BasicTest)379*635a8641SAndroid Build Coastguard Worker TEST_F(ActivityTrackerTest, BasicTest) {
380*635a8641SAndroid Build Coastguard Worker GlobalActivityTracker::CreateWithLocalMemory(kMemorySize, 0, "", 3, 0);
381*635a8641SAndroid Build Coastguard Worker GlobalActivityTracker* global = GlobalActivityTracker::Get();
382*635a8641SAndroid Build Coastguard Worker
383*635a8641SAndroid Build Coastguard Worker // Ensure the data repositories have backing store, indicated by non-zero ID.
384*635a8641SAndroid Build Coastguard Worker EXPECT_NE(0U, global->process_data().id());
385*635a8641SAndroid Build Coastguard Worker }
386*635a8641SAndroid Build Coastguard Worker
387*635a8641SAndroid Build Coastguard Worker namespace {
388*635a8641SAndroid Build Coastguard Worker
389*635a8641SAndroid Build Coastguard Worker class SimpleActivityThread : public SimpleThread {
390*635a8641SAndroid Build Coastguard Worker public:
SimpleActivityThread(const std::string & name,const void * origin,Activity::Type activity,const ActivityData & data)391*635a8641SAndroid Build Coastguard Worker SimpleActivityThread(const std::string& name,
392*635a8641SAndroid Build Coastguard Worker const void* origin,
393*635a8641SAndroid Build Coastguard Worker Activity::Type activity,
394*635a8641SAndroid Build Coastguard Worker const ActivityData& data)
395*635a8641SAndroid Build Coastguard Worker : SimpleThread(name, Options()),
396*635a8641SAndroid Build Coastguard Worker origin_(origin),
397*635a8641SAndroid Build Coastguard Worker activity_(activity),
398*635a8641SAndroid Build Coastguard Worker data_(data),
399*635a8641SAndroid Build Coastguard Worker ready_(false),
400*635a8641SAndroid Build Coastguard Worker exit_(false),
401*635a8641SAndroid Build Coastguard Worker exit_condition_(&lock_) {}
402*635a8641SAndroid Build Coastguard Worker
403*635a8641SAndroid Build Coastguard Worker ~SimpleActivityThread() override = default;
404*635a8641SAndroid Build Coastguard Worker
Run()405*635a8641SAndroid Build Coastguard Worker void Run() override {
406*635a8641SAndroid Build Coastguard Worker ThreadActivityTracker::ActivityId id =
407*635a8641SAndroid Build Coastguard Worker GlobalActivityTracker::Get()
408*635a8641SAndroid Build Coastguard Worker ->GetOrCreateTrackerForCurrentThread()
409*635a8641SAndroid Build Coastguard Worker ->PushActivity(origin_, activity_, data_);
410*635a8641SAndroid Build Coastguard Worker
411*635a8641SAndroid Build Coastguard Worker {
412*635a8641SAndroid Build Coastguard Worker AutoLock auto_lock(lock_);
413*635a8641SAndroid Build Coastguard Worker ready_.store(true, std::memory_order_release);
414*635a8641SAndroid Build Coastguard Worker while (!exit_.load(std::memory_order_relaxed))
415*635a8641SAndroid Build Coastguard Worker exit_condition_.Wait();
416*635a8641SAndroid Build Coastguard Worker }
417*635a8641SAndroid Build Coastguard Worker
418*635a8641SAndroid Build Coastguard Worker GlobalActivityTracker::Get()->GetTrackerForCurrentThread()->PopActivity(id);
419*635a8641SAndroid Build Coastguard Worker }
420*635a8641SAndroid Build Coastguard Worker
Exit()421*635a8641SAndroid Build Coastguard Worker void Exit() {
422*635a8641SAndroid Build Coastguard Worker AutoLock auto_lock(lock_);
423*635a8641SAndroid Build Coastguard Worker exit_.store(true, std::memory_order_relaxed);
424*635a8641SAndroid Build Coastguard Worker exit_condition_.Signal();
425*635a8641SAndroid Build Coastguard Worker }
426*635a8641SAndroid Build Coastguard Worker
WaitReady()427*635a8641SAndroid Build Coastguard Worker void WaitReady() {
428*635a8641SAndroid Build Coastguard Worker SPIN_FOR_1_SECOND_OR_UNTIL_TRUE(ready_.load(std::memory_order_acquire));
429*635a8641SAndroid Build Coastguard Worker }
430*635a8641SAndroid Build Coastguard Worker
431*635a8641SAndroid Build Coastguard Worker private:
432*635a8641SAndroid Build Coastguard Worker const void* origin_;
433*635a8641SAndroid Build Coastguard Worker Activity::Type activity_;
434*635a8641SAndroid Build Coastguard Worker ActivityData data_;
435*635a8641SAndroid Build Coastguard Worker
436*635a8641SAndroid Build Coastguard Worker std::atomic<bool> ready_;
437*635a8641SAndroid Build Coastguard Worker std::atomic<bool> exit_;
438*635a8641SAndroid Build Coastguard Worker Lock lock_;
439*635a8641SAndroid Build Coastguard Worker ConditionVariable exit_condition_;
440*635a8641SAndroid Build Coastguard Worker
441*635a8641SAndroid Build Coastguard Worker DISALLOW_COPY_AND_ASSIGN(SimpleActivityThread);
442*635a8641SAndroid Build Coastguard Worker };
443*635a8641SAndroid Build Coastguard Worker
444*635a8641SAndroid Build Coastguard Worker } // namespace
445*635a8641SAndroid Build Coastguard Worker
TEST_F(ActivityTrackerTest,ThreadDeathTest)446*635a8641SAndroid Build Coastguard Worker TEST_F(ActivityTrackerTest, ThreadDeathTest) {
447*635a8641SAndroid Build Coastguard Worker GlobalActivityTracker::CreateWithLocalMemory(kMemorySize, 0, "", 3, 0);
448*635a8641SAndroid Build Coastguard Worker GlobalActivityTracker::Get()->GetOrCreateTrackerForCurrentThread();
449*635a8641SAndroid Build Coastguard Worker const size_t starting_active = GetGlobalActiveTrackerCount();
450*635a8641SAndroid Build Coastguard Worker const size_t starting_inactive = GetGlobalInactiveTrackerCount();
451*635a8641SAndroid Build Coastguard Worker
452*635a8641SAndroid Build Coastguard Worker SimpleActivityThread t1("t1", nullptr, Activity::ACT_TASK,
453*635a8641SAndroid Build Coastguard Worker ActivityData::ForTask(11));
454*635a8641SAndroid Build Coastguard Worker t1.Start();
455*635a8641SAndroid Build Coastguard Worker t1.WaitReady();
456*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(starting_active + 1, GetGlobalActiveTrackerCount());
457*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(starting_inactive, GetGlobalInactiveTrackerCount());
458*635a8641SAndroid Build Coastguard Worker
459*635a8641SAndroid Build Coastguard Worker t1.Exit();
460*635a8641SAndroid Build Coastguard Worker t1.Join();
461*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(starting_active, GetGlobalActiveTrackerCount());
462*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(starting_inactive + 1, GetGlobalInactiveTrackerCount());
463*635a8641SAndroid Build Coastguard Worker
464*635a8641SAndroid Build Coastguard Worker // Start another thread and ensure it re-uses the existing memory.
465*635a8641SAndroid Build Coastguard Worker
466*635a8641SAndroid Build Coastguard Worker SimpleActivityThread t2("t2", nullptr, Activity::ACT_TASK,
467*635a8641SAndroid Build Coastguard Worker ActivityData::ForTask(22));
468*635a8641SAndroid Build Coastguard Worker t2.Start();
469*635a8641SAndroid Build Coastguard Worker t2.WaitReady();
470*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(starting_active + 1, GetGlobalActiveTrackerCount());
471*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(starting_inactive, GetGlobalInactiveTrackerCount());
472*635a8641SAndroid Build Coastguard Worker
473*635a8641SAndroid Build Coastguard Worker t2.Exit();
474*635a8641SAndroid Build Coastguard Worker t2.Join();
475*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(starting_active, GetGlobalActiveTrackerCount());
476*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(starting_inactive + 1, GetGlobalInactiveTrackerCount());
477*635a8641SAndroid Build Coastguard Worker }
478*635a8641SAndroid Build Coastguard Worker
TEST_F(ActivityTrackerTest,ProcessDeathTest)479*635a8641SAndroid Build Coastguard Worker TEST_F(ActivityTrackerTest, ProcessDeathTest) {
480*635a8641SAndroid Build Coastguard Worker // This doesn't actually create and destroy a process. Instead, it uses for-
481*635a8641SAndroid Build Coastguard Worker // testing interfaces to simulate data created by other processes.
482*635a8641SAndroid Build Coastguard Worker const int64_t other_process_id = GetCurrentProcId() + 1;
483*635a8641SAndroid Build Coastguard Worker
484*635a8641SAndroid Build Coastguard Worker GlobalActivityTracker::CreateWithLocalMemory(kMemorySize, 0, "", 3, 0);
485*635a8641SAndroid Build Coastguard Worker GlobalActivityTracker* global = GlobalActivityTracker::Get();
486*635a8641SAndroid Build Coastguard Worker ThreadActivityTracker* thread = global->GetOrCreateTrackerForCurrentThread();
487*635a8641SAndroid Build Coastguard Worker
488*635a8641SAndroid Build Coastguard Worker // Get callbacks for process exit.
489*635a8641SAndroid Build Coastguard Worker global->SetProcessExitCallback(
490*635a8641SAndroid Build Coastguard Worker Bind(&ActivityTrackerTest::HandleProcessExit, Unretained(this)));
491*635a8641SAndroid Build Coastguard Worker
492*635a8641SAndroid Build Coastguard Worker // Pretend than another process has started.
493*635a8641SAndroid Build Coastguard Worker global->RecordProcessLaunch(other_process_id, FILE_PATH_LITERAL("foo --bar"));
494*635a8641SAndroid Build Coastguard Worker
495*635a8641SAndroid Build Coastguard Worker // Do some activities.
496*635a8641SAndroid Build Coastguard Worker PendingTask task(FROM_HERE, DoNothing());
497*635a8641SAndroid Build Coastguard Worker ScopedTaskRunActivity activity(task);
498*635a8641SAndroid Build Coastguard Worker ActivityUserData& user_data = activity.user_data();
499*635a8641SAndroid Build Coastguard Worker ASSERT_NE(0U, user_data.id());
500*635a8641SAndroid Build Coastguard Worker
501*635a8641SAndroid Build Coastguard Worker // Get the memory-allocator references to that data.
502*635a8641SAndroid Build Coastguard Worker PersistentMemoryAllocator::Reference proc_data_ref =
503*635a8641SAndroid Build Coastguard Worker global->allocator()->GetAsReference(
504*635a8641SAndroid Build Coastguard Worker global->process_data().GetBaseAddress(),
505*635a8641SAndroid Build Coastguard Worker GlobalActivityTracker::kTypeIdProcessDataRecord);
506*635a8641SAndroid Build Coastguard Worker ASSERT_TRUE(proc_data_ref);
507*635a8641SAndroid Build Coastguard Worker PersistentMemoryAllocator::Reference tracker_ref =
508*635a8641SAndroid Build Coastguard Worker global->allocator()->GetAsReference(
509*635a8641SAndroid Build Coastguard Worker thread->GetBaseAddress(),
510*635a8641SAndroid Build Coastguard Worker GlobalActivityTracker::kTypeIdActivityTracker);
511*635a8641SAndroid Build Coastguard Worker ASSERT_TRUE(tracker_ref);
512*635a8641SAndroid Build Coastguard Worker PersistentMemoryAllocator::Reference user_data_ref =
513*635a8641SAndroid Build Coastguard Worker global->allocator()->GetAsReference(
514*635a8641SAndroid Build Coastguard Worker user_data.GetBaseAddress(),
515*635a8641SAndroid Build Coastguard Worker GlobalActivityTracker::kTypeIdUserDataRecord);
516*635a8641SAndroid Build Coastguard Worker ASSERT_TRUE(user_data_ref);
517*635a8641SAndroid Build Coastguard Worker
518*635a8641SAndroid Build Coastguard Worker // Make a copy of the thread-tracker state so it can be restored later.
519*635a8641SAndroid Build Coastguard Worker const size_t tracker_size = global->allocator()->GetAllocSize(tracker_ref);
520*635a8641SAndroid Build Coastguard Worker std::unique_ptr<char[]> tracker_copy(new char[tracker_size]);
521*635a8641SAndroid Build Coastguard Worker memcpy(tracker_copy.get(), thread->GetBaseAddress(), tracker_size);
522*635a8641SAndroid Build Coastguard Worker
523*635a8641SAndroid Build Coastguard Worker // Change the objects to appear to be owned by another process. Use a "past"
524*635a8641SAndroid Build Coastguard Worker // time so that exit-time is always later than create-time.
525*635a8641SAndroid Build Coastguard Worker const int64_t past_stamp = Time::Now().ToInternalValue() - 1;
526*635a8641SAndroid Build Coastguard Worker int64_t owning_id;
527*635a8641SAndroid Build Coastguard Worker int64_t stamp;
528*635a8641SAndroid Build Coastguard Worker ASSERT_TRUE(ActivityUserData::GetOwningProcessId(
529*635a8641SAndroid Build Coastguard Worker global->process_data().GetBaseAddress(), &owning_id, &stamp));
530*635a8641SAndroid Build Coastguard Worker EXPECT_NE(other_process_id, owning_id);
531*635a8641SAndroid Build Coastguard Worker ASSERT_TRUE(ThreadActivityTracker::GetOwningProcessId(
532*635a8641SAndroid Build Coastguard Worker thread->GetBaseAddress(), &owning_id, &stamp));
533*635a8641SAndroid Build Coastguard Worker EXPECT_NE(other_process_id, owning_id);
534*635a8641SAndroid Build Coastguard Worker ASSERT_TRUE(ActivityUserData::GetOwningProcessId(user_data.GetBaseAddress(),
535*635a8641SAndroid Build Coastguard Worker &owning_id, &stamp));
536*635a8641SAndroid Build Coastguard Worker EXPECT_NE(other_process_id, owning_id);
537*635a8641SAndroid Build Coastguard Worker global->process_data().SetOwningProcessIdForTesting(other_process_id,
538*635a8641SAndroid Build Coastguard Worker past_stamp);
539*635a8641SAndroid Build Coastguard Worker thread->SetOwningProcessIdForTesting(other_process_id, past_stamp);
540*635a8641SAndroid Build Coastguard Worker user_data.SetOwningProcessIdForTesting(other_process_id, past_stamp);
541*635a8641SAndroid Build Coastguard Worker ASSERT_TRUE(ActivityUserData::GetOwningProcessId(
542*635a8641SAndroid Build Coastguard Worker global->process_data().GetBaseAddress(), &owning_id, &stamp));
543*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(other_process_id, owning_id);
544*635a8641SAndroid Build Coastguard Worker ASSERT_TRUE(ThreadActivityTracker::GetOwningProcessId(
545*635a8641SAndroid Build Coastguard Worker thread->GetBaseAddress(), &owning_id, &stamp));
546*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(other_process_id, owning_id);
547*635a8641SAndroid Build Coastguard Worker ASSERT_TRUE(ActivityUserData::GetOwningProcessId(user_data.GetBaseAddress(),
548*635a8641SAndroid Build Coastguard Worker &owning_id, &stamp));
549*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(other_process_id, owning_id);
550*635a8641SAndroid Build Coastguard Worker
551*635a8641SAndroid Build Coastguard Worker // Check that process exit will perform callback and free the allocations.
552*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(0, exit_id_);
553*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(GlobalActivityTracker::kTypeIdProcessDataRecord,
554*635a8641SAndroid Build Coastguard Worker global->allocator()->GetType(proc_data_ref));
555*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(GlobalActivityTracker::kTypeIdActivityTracker,
556*635a8641SAndroid Build Coastguard Worker global->allocator()->GetType(tracker_ref));
557*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(GlobalActivityTracker::kTypeIdUserDataRecord,
558*635a8641SAndroid Build Coastguard Worker global->allocator()->GetType(user_data_ref));
559*635a8641SAndroid Build Coastguard Worker global->RecordProcessExit(other_process_id, 0);
560*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(other_process_id, exit_id_);
561*635a8641SAndroid Build Coastguard Worker EXPECT_EQ("foo --bar", exit_command_);
562*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(GlobalActivityTracker::kTypeIdProcessDataRecordFree,
563*635a8641SAndroid Build Coastguard Worker global->allocator()->GetType(proc_data_ref));
564*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(GlobalActivityTracker::kTypeIdActivityTrackerFree,
565*635a8641SAndroid Build Coastguard Worker global->allocator()->GetType(tracker_ref));
566*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(GlobalActivityTracker::kTypeIdUserDataRecordFree,
567*635a8641SAndroid Build Coastguard Worker global->allocator()->GetType(user_data_ref));
568*635a8641SAndroid Build Coastguard Worker
569*635a8641SAndroid Build Coastguard Worker // Restore memory contents and types so things don't crash when doing real
570*635a8641SAndroid Build Coastguard Worker // process clean-up.
571*635a8641SAndroid Build Coastguard Worker memcpy(const_cast<void*>(thread->GetBaseAddress()), tracker_copy.get(),
572*635a8641SAndroid Build Coastguard Worker tracker_size);
573*635a8641SAndroid Build Coastguard Worker global->allocator()->ChangeType(
574*635a8641SAndroid Build Coastguard Worker proc_data_ref, GlobalActivityTracker::kTypeIdProcessDataRecord,
575*635a8641SAndroid Build Coastguard Worker GlobalActivityTracker::kTypeIdUserDataRecordFree, false);
576*635a8641SAndroid Build Coastguard Worker global->allocator()->ChangeType(
577*635a8641SAndroid Build Coastguard Worker tracker_ref, GlobalActivityTracker::kTypeIdActivityTracker,
578*635a8641SAndroid Build Coastguard Worker GlobalActivityTracker::kTypeIdActivityTrackerFree, false);
579*635a8641SAndroid Build Coastguard Worker global->allocator()->ChangeType(
580*635a8641SAndroid Build Coastguard Worker user_data_ref, GlobalActivityTracker::kTypeIdUserDataRecord,
581*635a8641SAndroid Build Coastguard Worker GlobalActivityTracker::kTypeIdUserDataRecordFree, false);
582*635a8641SAndroid Build Coastguard Worker }
583*635a8641SAndroid Build Coastguard Worker
584*635a8641SAndroid Build Coastguard Worker } // namespace debug
585*635a8641SAndroid Build Coastguard Worker } // namespace base
586