OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/debug/activity_analyzer.h" | 5 #include "base/debug/activity_analyzer.h" |
6 | 6 |
7 #include <atomic> | 7 #include <atomic> |
8 #include <memory> | 8 #include <memory> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
11 #include "base/debug/activity_tracker.h" | 11 #include "base/debug/activity_tracker.h" |
12 #include "base/files/file.h" | 12 #include "base/files/file.h" |
13 #include "base/files/file_util.h" | 13 #include "base/files/file_util.h" |
14 #include "base/files/memory_mapped_file.h" | 14 #include "base/files/memory_mapped_file.h" |
15 #include "base/files/scoped_temp_dir.h" | 15 #include "base/files/scoped_temp_dir.h" |
16 #include "base/memory/ptr_util.h" | 16 #include "base/memory/ptr_util.h" |
17 #include "base/pending_task.h" | 17 #include "base/pending_task.h" |
18 #include "base/process/process.h" | 18 #include "base/process/process.h" |
| 19 #include "base/stl_util.h" |
19 #include "base/synchronization/condition_variable.h" | 20 #include "base/synchronization/condition_variable.h" |
20 #include "base/synchronization/lock.h" | 21 #include "base/synchronization/lock.h" |
21 #include "base/synchronization/spin_wait.h" | 22 #include "base/synchronization/spin_wait.h" |
22 #include "base/threading/platform_thread.h" | 23 #include "base/threading/platform_thread.h" |
23 #include "base/threading/simple_thread.h" | 24 #include "base/threading/simple_thread.h" |
24 #include "base/time/time.h" | 25 #include "base/time/time.h" |
25 #include "testing/gtest/include/gtest/gtest.h" | 26 #include "testing/gtest/include/gtest/gtest.h" |
26 | 27 |
27 namespace base { | 28 namespace base { |
28 namespace debug { | 29 namespace debug { |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
169 // Now there should be only one again. Calling GetFirstAnalyzer invalidates | 170 // Now there should be only one again. Calling GetFirstAnalyzer invalidates |
170 // any previously returned analyzer pointers. | 171 // any previously returned analyzer pointers. |
171 ThreadActivityAnalyzer* ta2 = analyzer.GetFirstAnalyzer(); | 172 ThreadActivityAnalyzer* ta2 = analyzer.GetFirstAnalyzer(); |
172 ASSERT_TRUE(ta2); | 173 ASSERT_TRUE(ta2); |
173 EXPECT_FALSE(analyzer.GetNextAnalyzer()); | 174 EXPECT_FALSE(analyzer.GetNextAnalyzer()); |
174 ThreadActivityAnalyzer::ThreadKey tk2 = ta2->GetThreadKey(); | 175 ThreadActivityAnalyzer::ThreadKey tk2 = ta2->GetThreadKey(); |
175 EXPECT_EQ(ta2, analyzer.GetAnalyzerForThread(tk2)); | 176 EXPECT_EQ(ta2, analyzer.GetAnalyzerForThread(tk2)); |
176 EXPECT_EQ(tk1, tk2); | 177 EXPECT_EQ(tk1, tk2); |
177 } | 178 } |
178 | 179 |
| 180 TEST_F(ActivityAnalyzerTest, UserDataSnapshotTest) { |
| 181 GlobalActivityTracker::CreateWithLocalMemory(kMemorySize, 0, "", 3); |
| 182 ThreadActivityAnalyzer::Snapshot snapshot; |
| 183 |
| 184 const char string1a[] = "string1a"; |
| 185 const char string1b[] = "string1b"; |
| 186 const char string2a[] = "string2a"; |
| 187 const char string2b[] = "string2b"; |
| 188 |
| 189 PersistentMemoryAllocator* allocator = |
| 190 GlobalActivityTracker::Get()->allocator(); |
| 191 GlobalActivityAnalyzer global_analyzer(MakeUnique<PersistentMemoryAllocator>( |
| 192 const_cast<void*>(allocator->data()), allocator->size(), 0, 0, "", true)); |
| 193 |
| 194 ThreadActivityTracker* tracker = |
| 195 GlobalActivityTracker::Get()->GetOrCreateTrackerForCurrentThread(); |
| 196 |
| 197 { |
| 198 ScopedActivity activity1(1, 11, 111); |
| 199 ActivityUserData& user_data1 = activity1.user_data(); |
| 200 user_data1.Set("raw1", "foo1", 4); |
| 201 user_data1.SetString("string1", "bar1"); |
| 202 user_data1.SetChar("char1", '1'); |
| 203 user_data1.SetInt("int1", -1111); |
| 204 user_data1.SetUint("uint1", 1111); |
| 205 user_data1.SetBool("bool1", true); |
| 206 user_data1.SetReference("ref1", string1a, sizeof(string1a)); |
| 207 user_data1.SetStringReference("sref1", string1b); |
| 208 |
| 209 { |
| 210 ScopedActivity activity2(2, 22, 222); |
| 211 ActivityUserData& user_data2 = activity2.user_data(); |
| 212 user_data2.Set("raw2", "foo2", 4); |
| 213 user_data2.SetString("string2", "bar2"); |
| 214 user_data2.SetChar("char2", '2'); |
| 215 user_data2.SetInt("int2", -2222); |
| 216 user_data2.SetUint("uint2", 2222); |
| 217 user_data2.SetBool("bool2", false); |
| 218 user_data2.SetReference("ref2", string2a, sizeof(string2a)); |
| 219 user_data2.SetStringReference("sref2", string2b); |
| 220 |
| 221 ASSERT_TRUE(tracker->CreateSnapshot(&snapshot)); |
| 222 ASSERT_EQ(2U, snapshot.activity_stack.size()); |
| 223 |
| 224 ThreadActivityAnalyzer analyzer(*tracker); |
| 225 analyzer.AddGlobalInformation(&global_analyzer); |
| 226 const ThreadActivityAnalyzer::Snapshot& snapshot = |
| 227 analyzer.activity_snapshot(); |
| 228 ASSERT_EQ(2U, snapshot.user_data_stack.size()); |
| 229 const ActivityUserData::Snapshot& user_data = |
| 230 snapshot.user_data_stack.at(1); |
| 231 EXPECT_EQ(8U, user_data.size()); |
| 232 ASSERT_TRUE(ContainsKey(user_data, "raw2")); |
| 233 EXPECT_EQ("foo2", user_data.at("raw2").Get().as_string()); |
| 234 ASSERT_TRUE(ContainsKey(user_data, "string2")); |
| 235 EXPECT_EQ("bar2", user_data.at("string2").GetString().as_string()); |
| 236 ASSERT_TRUE(ContainsKey(user_data, "char2")); |
| 237 EXPECT_EQ('2', user_data.at("char2").GetChar()); |
| 238 ASSERT_TRUE(ContainsKey(user_data, "int2")); |
| 239 EXPECT_EQ(-2222, user_data.at("int2").GetInt()); |
| 240 ASSERT_TRUE(ContainsKey(user_data, "uint2")); |
| 241 EXPECT_EQ(2222U, user_data.at("uint2").GetUint()); |
| 242 ASSERT_TRUE(ContainsKey(user_data, "bool2")); |
| 243 EXPECT_FALSE(user_data.at("bool2").GetBool()); |
| 244 ASSERT_TRUE(ContainsKey(user_data, "ref2")); |
| 245 EXPECT_EQ(string2a, user_data.at("ref2").GetReference().data()); |
| 246 EXPECT_EQ(sizeof(string2a), user_data.at("ref2").GetReference().size()); |
| 247 ASSERT_TRUE(ContainsKey(user_data, "sref2")); |
| 248 EXPECT_EQ(string2b, user_data.at("sref2").GetStringReference().data()); |
| 249 EXPECT_EQ(strlen(string2b), |
| 250 user_data.at("sref2").GetStringReference().size()); |
| 251 } |
| 252 |
| 253 ASSERT_TRUE(tracker->CreateSnapshot(&snapshot)); |
| 254 ASSERT_EQ(1U, snapshot.activity_stack.size()); |
| 255 |
| 256 ThreadActivityAnalyzer analyzer(*tracker); |
| 257 analyzer.AddGlobalInformation(&global_analyzer); |
| 258 const ThreadActivityAnalyzer::Snapshot& snapshot = |
| 259 analyzer.activity_snapshot(); |
| 260 ASSERT_EQ(1U, snapshot.user_data_stack.size()); |
| 261 const ActivityUserData::Snapshot& user_data = |
| 262 snapshot.user_data_stack.at(0); |
| 263 EXPECT_EQ(8U, user_data.size()); |
| 264 EXPECT_EQ("foo1", user_data.at("raw1").Get().as_string()); |
| 265 EXPECT_EQ("bar1", user_data.at("string1").GetString().as_string()); |
| 266 EXPECT_EQ('1', user_data.at("char1").GetChar()); |
| 267 EXPECT_EQ(-1111, user_data.at("int1").GetInt()); |
| 268 EXPECT_EQ(1111U, user_data.at("uint1").GetUint()); |
| 269 EXPECT_TRUE(user_data.at("bool1").GetBool()); |
| 270 EXPECT_EQ(string1a, user_data.at("ref1").GetReference().data()); |
| 271 EXPECT_EQ(sizeof(string1a), user_data.at("ref1").GetReference().size()); |
| 272 EXPECT_EQ(string1b, user_data.at("sref1").GetStringReference().data()); |
| 273 EXPECT_EQ(strlen(string1b), |
| 274 user_data.at("sref1").GetStringReference().size()); |
| 275 } |
| 276 |
| 277 ASSERT_TRUE(tracker->CreateSnapshot(&snapshot)); |
| 278 ASSERT_EQ(0U, snapshot.activity_stack.size()); |
| 279 } |
| 280 |
| 281 TEST_F(ActivityAnalyzerTest, GlobalUserDataTest) { |
| 282 GlobalActivityTracker::CreateWithLocalMemory(kMemorySize, 0, "", 3); |
| 283 |
| 284 const char string1[] = "foo"; |
| 285 const char string2[] = "bar"; |
| 286 |
| 287 PersistentMemoryAllocator* allocator = |
| 288 GlobalActivityTracker::Get()->allocator(); |
| 289 GlobalActivityAnalyzer global_analyzer(MakeUnique<PersistentMemoryAllocator>( |
| 290 const_cast<void*>(allocator->data()), allocator->size(), 0, 0, "", true)); |
| 291 |
| 292 ActivityUserData& global_data = GlobalActivityTracker::Get()->user_data(); |
| 293 global_data.Set("raw", "foo", 3); |
| 294 global_data.SetString("string", "bar"); |
| 295 global_data.SetChar("char", '9'); |
| 296 global_data.SetInt("int", -9999); |
| 297 global_data.SetUint("uint", 9999); |
| 298 global_data.SetBool("bool", true); |
| 299 global_data.SetReference("ref", string1, sizeof(string1)); |
| 300 global_data.SetStringReference("sref", string2); |
| 301 |
| 302 ActivityUserData::Snapshot snapshot = |
| 303 global_analyzer.GetGlobalUserDataSnapshot(); |
| 304 ASSERT_TRUE(ContainsKey(snapshot, "raw")); |
| 305 EXPECT_EQ("foo", snapshot.at("raw").Get().as_string()); |
| 306 ASSERT_TRUE(ContainsKey(snapshot, "string")); |
| 307 EXPECT_EQ("bar", snapshot.at("string").GetString().as_string()); |
| 308 ASSERT_TRUE(ContainsKey(snapshot, "char")); |
| 309 EXPECT_EQ('9', snapshot.at("char").GetChar()); |
| 310 ASSERT_TRUE(ContainsKey(snapshot, "int")); |
| 311 EXPECT_EQ(-9999, snapshot.at("int").GetInt()); |
| 312 ASSERT_TRUE(ContainsKey(snapshot, "uint")); |
| 313 EXPECT_EQ(9999U, snapshot.at("uint").GetUint()); |
| 314 ASSERT_TRUE(ContainsKey(snapshot, "bool")); |
| 315 EXPECT_TRUE(snapshot.at("bool").GetBool()); |
| 316 ASSERT_TRUE(ContainsKey(snapshot, "ref")); |
| 317 EXPECT_EQ(string1, snapshot.at("ref").GetReference().data()); |
| 318 EXPECT_EQ(sizeof(string1), snapshot.at("ref").GetReference().size()); |
| 319 ASSERT_TRUE(ContainsKey(snapshot, "sref")); |
| 320 EXPECT_EQ(string2, snapshot.at("sref").GetStringReference().data()); |
| 321 EXPECT_EQ(strlen(string2), snapshot.at("sref").GetStringReference().size()); |
| 322 } |
| 323 |
179 } // namespace debug | 324 } // namespace debug |
180 } // namespace base | 325 } // namespace base |
OLD | NEW |