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" |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
132 std::atomic<bool> ready_; | 132 std::atomic<bool> ready_; |
133 std::atomic<bool> exit_; | 133 std::atomic<bool> exit_; |
134 Lock lock_; | 134 Lock lock_; |
135 ConditionVariable exit_condition_; | 135 ConditionVariable exit_condition_; |
136 | 136 |
137 DISALLOW_COPY_AND_ASSIGN(SimpleActivityThread); | 137 DISALLOW_COPY_AND_ASSIGN(SimpleActivityThread); |
138 }; | 138 }; |
139 | 139 |
140 TEST_F(ActivityAnalyzerTest, GlobalAnalyzerConstruction) { | 140 TEST_F(ActivityAnalyzerTest, GlobalAnalyzerConstruction) { |
141 GlobalActivityTracker::CreateWithLocalMemory(kMemorySize, 0, "", 3); | 141 GlobalActivityTracker::CreateWithLocalMemory(kMemorySize, 0, "", 3); |
| 142 GlobalActivityTracker::Get()->process_data().SetString("foo", "bar"); |
142 | 143 |
143 PersistentMemoryAllocator* allocator = | 144 PersistentMemoryAllocator* allocator = |
144 GlobalActivityTracker::Get()->allocator(); | 145 GlobalActivityTracker::Get()->allocator(); |
145 GlobalActivityAnalyzer analyzer(MakeUnique<PersistentMemoryAllocator>( | 146 GlobalActivityAnalyzer analyzer(MakeUnique<PersistentMemoryAllocator>( |
146 const_cast<void*>(allocator->data()), allocator->size(), 0, 0, "", true)); | 147 const_cast<void*>(allocator->data()), allocator->size(), 0, 0, "", true)); |
147 | 148 |
148 // The only thread at thois point is the test thread. | 149 // The only thread at this point is the test thread of this process. |
149 ThreadActivityAnalyzer* ta1 = analyzer.GetFirstAnalyzer(); | 150 const int64_t pid = analyzer.GetFirstProcess(); |
| 151 ASSERT_NE(0, pid); |
| 152 ThreadActivityAnalyzer* ta1 = analyzer.GetFirstAnalyzer(pid); |
150 ASSERT_TRUE(ta1); | 153 ASSERT_TRUE(ta1); |
151 EXPECT_FALSE(analyzer.GetNextAnalyzer()); | 154 EXPECT_FALSE(analyzer.GetNextAnalyzer(pid)); |
152 ThreadActivityAnalyzer::ThreadKey tk1 = ta1->GetThreadKey(); | 155 ThreadActivityAnalyzer::ThreadKey tk1 = ta1->GetThreadKey(); |
153 EXPECT_EQ(ta1, analyzer.GetAnalyzerForThread(tk1)); | 156 EXPECT_EQ(ta1, analyzer.GetAnalyzerForThread(tk1)); |
| 157 EXPECT_EQ(0, analyzer.GetNextProcess()); |
154 | 158 |
155 // Create a second thread that will do something. | 159 // Create a second thread that will do something. |
156 SimpleActivityThread t2("t2", nullptr, Activity::ACT_TASK, | 160 SimpleActivityThread t2("t2", nullptr, Activity::ACT_TASK, |
157 ActivityData::ForTask(11)); | 161 ActivityData::ForTask(11)); |
158 t2.Start(); | 162 t2.Start(); |
159 t2.WaitReady(); | 163 t2.WaitReady(); |
160 | 164 |
161 // Now there should be two. | 165 // Now there should be two. Calling GetFirstProcess invalidates any |
162 EXPECT_TRUE(analyzer.GetFirstAnalyzer()); | 166 // previously returned analyzer pointers. |
163 EXPECT_TRUE(analyzer.GetNextAnalyzer()); | 167 ASSERT_EQ(pid, analyzer.GetFirstProcess()); |
164 EXPECT_FALSE(analyzer.GetNextAnalyzer()); | 168 EXPECT_TRUE(analyzer.GetFirstAnalyzer(pid)); |
| 169 EXPECT_TRUE(analyzer.GetNextAnalyzer(pid)); |
| 170 EXPECT_FALSE(analyzer.GetNextAnalyzer(pid)); |
| 171 EXPECT_EQ(0, analyzer.GetNextProcess()); |
165 | 172 |
166 // Let thread exit. | 173 // Let thread exit. |
167 t2.Exit(); | 174 t2.Exit(); |
168 t2.Join(); | 175 t2.Join(); |
169 | 176 |
170 // Now there should be only one again. Calling GetFirstAnalyzer invalidates | 177 // Now there should be only one again. |
171 // any previously returned analyzer pointers. | 178 ASSERT_EQ(pid, analyzer.GetFirstProcess()); |
172 ThreadActivityAnalyzer* ta2 = analyzer.GetFirstAnalyzer(); | 179 ThreadActivityAnalyzer* ta2 = analyzer.GetFirstAnalyzer(pid); |
173 ASSERT_TRUE(ta2); | 180 ASSERT_TRUE(ta2); |
174 EXPECT_FALSE(analyzer.GetNextAnalyzer()); | 181 EXPECT_FALSE(analyzer.GetNextAnalyzer(pid)); |
175 ThreadActivityAnalyzer::ThreadKey tk2 = ta2->GetThreadKey(); | 182 ThreadActivityAnalyzer::ThreadKey tk2 = ta2->GetThreadKey(); |
176 EXPECT_EQ(ta2, analyzer.GetAnalyzerForThread(tk2)); | 183 EXPECT_EQ(ta2, analyzer.GetAnalyzerForThread(tk2)); |
177 EXPECT_EQ(tk1, tk2); | 184 EXPECT_EQ(tk1, tk2); |
| 185 EXPECT_EQ(0, analyzer.GetNextProcess()); |
| 186 |
| 187 // Verify that there is process data. |
| 188 const ActivityUserData::Snapshot& data_snapshot = |
| 189 analyzer.GetProcessDataSnapshot(pid); |
| 190 ASSERT_LE(1U, data_snapshot.size()); |
| 191 EXPECT_EQ("bar", data_snapshot.at("foo").GetString()); |
178 } | 192 } |
179 | 193 |
180 TEST_F(ActivityAnalyzerTest, UserDataSnapshotTest) { | 194 TEST_F(ActivityAnalyzerTest, UserDataSnapshotTest) { |
181 GlobalActivityTracker::CreateWithLocalMemory(kMemorySize, 0, "", 3); | 195 GlobalActivityTracker::CreateWithLocalMemory(kMemorySize, 0, "", 3); |
182 ThreadActivityAnalyzer::Snapshot snapshot; | 196 ThreadActivityAnalyzer::Snapshot tracker_snapshot; |
183 | 197 |
184 const char string1a[] = "string1a"; | 198 const char string1a[] = "string1a"; |
185 const char string1b[] = "string1b"; | 199 const char string1b[] = "string1b"; |
186 const char string2a[] = "string2a"; | 200 const char string2a[] = "string2a"; |
187 const char string2b[] = "string2b"; | 201 const char string2b[] = "string2b"; |
188 | 202 |
189 PersistentMemoryAllocator* allocator = | 203 PersistentMemoryAllocator* allocator = |
190 GlobalActivityTracker::Get()->allocator(); | 204 GlobalActivityTracker::Get()->allocator(); |
191 GlobalActivityAnalyzer global_analyzer(MakeUnique<PersistentMemoryAllocator>( | 205 GlobalActivityAnalyzer global_analyzer(MakeUnique<PersistentMemoryAllocator>( |
192 const_cast<void*>(allocator->data()), allocator->size(), 0, 0, "", true)); | 206 const_cast<void*>(allocator->data()), allocator->size(), 0, 0, "", true)); |
(...skipping 18 matching lines...) Expand all Loading... |
211 ActivityUserData& user_data2 = activity2.user_data(); | 225 ActivityUserData& user_data2 = activity2.user_data(); |
212 user_data2.Set("raw2", "foo2", 4); | 226 user_data2.Set("raw2", "foo2", 4); |
213 user_data2.SetString("string2", "bar2"); | 227 user_data2.SetString("string2", "bar2"); |
214 user_data2.SetChar("char2", '2'); | 228 user_data2.SetChar("char2", '2'); |
215 user_data2.SetInt("int2", -2222); | 229 user_data2.SetInt("int2", -2222); |
216 user_data2.SetUint("uint2", 2222); | 230 user_data2.SetUint("uint2", 2222); |
217 user_data2.SetBool("bool2", false); | 231 user_data2.SetBool("bool2", false); |
218 user_data2.SetReference("ref2", string2a, sizeof(string2a)); | 232 user_data2.SetReference("ref2", string2a, sizeof(string2a)); |
219 user_data2.SetStringReference("sref2", string2b); | 233 user_data2.SetStringReference("sref2", string2b); |
220 | 234 |
221 ASSERT_TRUE(tracker->CreateSnapshot(&snapshot)); | 235 ASSERT_TRUE(tracker->CreateSnapshot(&tracker_snapshot)); |
222 ASSERT_EQ(2U, snapshot.activity_stack.size()); | 236 ASSERT_EQ(2U, tracker_snapshot.activity_stack.size()); |
223 | 237 |
224 ThreadActivityAnalyzer analyzer(*tracker); | 238 ThreadActivityAnalyzer analyzer(*tracker); |
225 analyzer.AddGlobalInformation(&global_analyzer); | 239 analyzer.AddGlobalInformation(&global_analyzer); |
226 const ThreadActivityAnalyzer::Snapshot& snapshot = | 240 const ThreadActivityAnalyzer::Snapshot& analyzer_snapshot = |
227 analyzer.activity_snapshot(); | 241 analyzer.activity_snapshot(); |
228 ASSERT_EQ(2U, snapshot.user_data_stack.size()); | 242 ASSERT_EQ(2U, analyzer_snapshot.user_data_stack.size()); |
229 const ActivityUserData::Snapshot& user_data = | 243 const ActivityUserData::Snapshot& user_data = |
230 snapshot.user_data_stack.at(1); | 244 analyzer_snapshot.user_data_stack.at(1); |
231 EXPECT_EQ(8U, user_data.size()); | 245 EXPECT_EQ(8U, user_data.size()); |
232 ASSERT_TRUE(ContainsKey(user_data, "raw2")); | 246 ASSERT_TRUE(ContainsKey(user_data, "raw2")); |
233 EXPECT_EQ("foo2", user_data.at("raw2").Get().as_string()); | 247 EXPECT_EQ("foo2", user_data.at("raw2").Get().as_string()); |
234 ASSERT_TRUE(ContainsKey(user_data, "string2")); | 248 ASSERT_TRUE(ContainsKey(user_data, "string2")); |
235 EXPECT_EQ("bar2", user_data.at("string2").GetString().as_string()); | 249 EXPECT_EQ("bar2", user_data.at("string2").GetString().as_string()); |
236 ASSERT_TRUE(ContainsKey(user_data, "char2")); | 250 ASSERT_TRUE(ContainsKey(user_data, "char2")); |
237 EXPECT_EQ('2', user_data.at("char2").GetChar()); | 251 EXPECT_EQ('2', user_data.at("char2").GetChar()); |
238 ASSERT_TRUE(ContainsKey(user_data, "int2")); | 252 ASSERT_TRUE(ContainsKey(user_data, "int2")); |
239 EXPECT_EQ(-2222, user_data.at("int2").GetInt()); | 253 EXPECT_EQ(-2222, user_data.at("int2").GetInt()); |
240 ASSERT_TRUE(ContainsKey(user_data, "uint2")); | 254 ASSERT_TRUE(ContainsKey(user_data, "uint2")); |
241 EXPECT_EQ(2222U, user_data.at("uint2").GetUint()); | 255 EXPECT_EQ(2222U, user_data.at("uint2").GetUint()); |
242 ASSERT_TRUE(ContainsKey(user_data, "bool2")); | 256 ASSERT_TRUE(ContainsKey(user_data, "bool2")); |
243 EXPECT_FALSE(user_data.at("bool2").GetBool()); | 257 EXPECT_FALSE(user_data.at("bool2").GetBool()); |
244 ASSERT_TRUE(ContainsKey(user_data, "ref2")); | 258 ASSERT_TRUE(ContainsKey(user_data, "ref2")); |
245 EXPECT_EQ(string2a, user_data.at("ref2").GetReference().data()); | 259 EXPECT_EQ(string2a, user_data.at("ref2").GetReference().data()); |
246 EXPECT_EQ(sizeof(string2a), user_data.at("ref2").GetReference().size()); | 260 EXPECT_EQ(sizeof(string2a), user_data.at("ref2").GetReference().size()); |
247 ASSERT_TRUE(ContainsKey(user_data, "sref2")); | 261 ASSERT_TRUE(ContainsKey(user_data, "sref2")); |
248 EXPECT_EQ(string2b, user_data.at("sref2").GetStringReference().data()); | 262 EXPECT_EQ(string2b, user_data.at("sref2").GetStringReference().data()); |
249 EXPECT_EQ(strlen(string2b), | 263 EXPECT_EQ(strlen(string2b), |
250 user_data.at("sref2").GetStringReference().size()); | 264 user_data.at("sref2").GetStringReference().size()); |
251 } | 265 } |
252 | 266 |
253 ASSERT_TRUE(tracker->CreateSnapshot(&snapshot)); | 267 ASSERT_TRUE(tracker->CreateSnapshot(&tracker_snapshot)); |
254 ASSERT_EQ(1U, snapshot.activity_stack.size()); | 268 ASSERT_EQ(1U, tracker_snapshot.activity_stack.size()); |
255 | 269 |
256 ThreadActivityAnalyzer analyzer(*tracker); | 270 ThreadActivityAnalyzer analyzer(*tracker); |
257 analyzer.AddGlobalInformation(&global_analyzer); | 271 analyzer.AddGlobalInformation(&global_analyzer); |
258 const ThreadActivityAnalyzer::Snapshot& snapshot = | 272 const ThreadActivityAnalyzer::Snapshot& analyzer_snapshot = |
259 analyzer.activity_snapshot(); | 273 analyzer.activity_snapshot(); |
260 ASSERT_EQ(1U, snapshot.user_data_stack.size()); | 274 ASSERT_EQ(1U, analyzer_snapshot.user_data_stack.size()); |
261 const ActivityUserData::Snapshot& user_data = | 275 const ActivityUserData::Snapshot& user_data = |
262 snapshot.user_data_stack.at(0); | 276 analyzer_snapshot.user_data_stack.at(0); |
263 EXPECT_EQ(8U, user_data.size()); | 277 EXPECT_EQ(8U, user_data.size()); |
264 EXPECT_EQ("foo1", user_data.at("raw1").Get().as_string()); | 278 EXPECT_EQ("foo1", user_data.at("raw1").Get().as_string()); |
265 EXPECT_EQ("bar1", user_data.at("string1").GetString().as_string()); | 279 EXPECT_EQ("bar1", user_data.at("string1").GetString().as_string()); |
266 EXPECT_EQ('1', user_data.at("char1").GetChar()); | 280 EXPECT_EQ('1', user_data.at("char1").GetChar()); |
267 EXPECT_EQ(-1111, user_data.at("int1").GetInt()); | 281 EXPECT_EQ(-1111, user_data.at("int1").GetInt()); |
268 EXPECT_EQ(1111U, user_data.at("uint1").GetUint()); | 282 EXPECT_EQ(1111U, user_data.at("uint1").GetUint()); |
269 EXPECT_TRUE(user_data.at("bool1").GetBool()); | 283 EXPECT_TRUE(user_data.at("bool1").GetBool()); |
270 EXPECT_EQ(string1a, user_data.at("ref1").GetReference().data()); | 284 EXPECT_EQ(string1a, user_data.at("ref1").GetReference().data()); |
271 EXPECT_EQ(sizeof(string1a), user_data.at("ref1").GetReference().size()); | 285 EXPECT_EQ(sizeof(string1a), user_data.at("ref1").GetReference().size()); |
272 EXPECT_EQ(string1b, user_data.at("sref1").GetStringReference().data()); | 286 EXPECT_EQ(string1b, user_data.at("sref1").GetStringReference().data()); |
273 EXPECT_EQ(strlen(string1b), | 287 EXPECT_EQ(strlen(string1b), |
274 user_data.at("sref1").GetStringReference().size()); | 288 user_data.at("sref1").GetStringReference().size()); |
275 } | 289 } |
276 | 290 |
277 ASSERT_TRUE(tracker->CreateSnapshot(&snapshot)); | 291 ASSERT_TRUE(tracker->CreateSnapshot(&tracker_snapshot)); |
278 ASSERT_EQ(0U, snapshot.activity_stack.size()); | 292 ASSERT_EQ(0U, tracker_snapshot.activity_stack.size()); |
279 } | 293 } |
280 | 294 |
281 TEST_F(ActivityAnalyzerTest, GlobalUserDataTest) { | 295 TEST_F(ActivityAnalyzerTest, GlobalUserDataTest) { |
282 GlobalActivityTracker::CreateWithLocalMemory(kMemorySize, 0, "", 3); | 296 GlobalActivityTracker::CreateWithLocalMemory(kMemorySize, 0, "", 3); |
283 | 297 |
284 const char string1[] = "foo"; | 298 const char string1[] = "foo"; |
285 const char string2[] = "bar"; | 299 const char string2[] = "bar"; |
286 | 300 |
287 PersistentMemoryAllocator* allocator = | 301 PersistentMemoryAllocator* allocator = |
288 GlobalActivityTracker::Get()->allocator(); | 302 GlobalActivityTracker::Get()->allocator(); |
289 GlobalActivityAnalyzer global_analyzer(MakeUnique<PersistentMemoryAllocator>( | 303 GlobalActivityAnalyzer global_analyzer(MakeUnique<PersistentMemoryAllocator>( |
290 const_cast<void*>(allocator->data()), allocator->size(), 0, 0, "", true)); | 304 const_cast<void*>(allocator->data()), allocator->size(), 0, 0, "", true)); |
291 | 305 |
292 ActivityUserData& global_data = GlobalActivityTracker::Get()->global_data(); | 306 ActivityUserData& global_data = GlobalActivityTracker::Get()->global_data(); |
293 global_data.Set("raw", "foo", 3); | 307 global_data.Set("raw", "foo", 3); |
294 global_data.SetString("string", "bar"); | 308 global_data.SetString("string", "bar"); |
295 global_data.SetChar("char", '9'); | 309 global_data.SetChar("char", '9'); |
296 global_data.SetInt("int", -9999); | 310 global_data.SetInt("int", -9999); |
297 global_data.SetUint("uint", 9999); | 311 global_data.SetUint("uint", 9999); |
298 global_data.SetBool("bool", true); | 312 global_data.SetBool("bool", true); |
299 global_data.SetReference("ref", string1, sizeof(string1)); | 313 global_data.SetReference("ref", string1, sizeof(string1)); |
300 global_data.SetStringReference("sref", string2); | 314 global_data.SetStringReference("sref", string2); |
301 | 315 |
302 ActivityUserData::Snapshot snapshot = | 316 const ActivityUserData::Snapshot& snapshot = |
303 global_analyzer.GetGlobalUserDataSnapshot(); | 317 global_analyzer.GetGlobalDataSnapshot(); |
304 ASSERT_TRUE(ContainsKey(snapshot, "raw")); | 318 ASSERT_TRUE(ContainsKey(snapshot, "raw")); |
305 EXPECT_EQ("foo", snapshot.at("raw").Get().as_string()); | 319 EXPECT_EQ("foo", snapshot.at("raw").Get().as_string()); |
306 ASSERT_TRUE(ContainsKey(snapshot, "string")); | 320 ASSERT_TRUE(ContainsKey(snapshot, "string")); |
307 EXPECT_EQ("bar", snapshot.at("string").GetString().as_string()); | 321 EXPECT_EQ("bar", snapshot.at("string").GetString().as_string()); |
308 ASSERT_TRUE(ContainsKey(snapshot, "char")); | 322 ASSERT_TRUE(ContainsKey(snapshot, "char")); |
309 EXPECT_EQ('9', snapshot.at("char").GetChar()); | 323 EXPECT_EQ('9', snapshot.at("char").GetChar()); |
310 ASSERT_TRUE(ContainsKey(snapshot, "int")); | 324 ASSERT_TRUE(ContainsKey(snapshot, "int")); |
311 EXPECT_EQ(-9999, snapshot.at("int").GetInt()); | 325 EXPECT_EQ(-9999, snapshot.at("int").GetInt()); |
312 ASSERT_TRUE(ContainsKey(snapshot, "uint")); | 326 ASSERT_TRUE(ContainsKey(snapshot, "uint")); |
313 EXPECT_EQ(9999U, snapshot.at("uint").GetUint()); | 327 EXPECT_EQ(9999U, snapshot.at("uint").GetUint()); |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
409 GlobalActivityTracker::Get()->RecordLogMessage("foo bar"); | 423 GlobalActivityTracker::Get()->RecordLogMessage("foo bar"); |
410 | 424 |
411 std::vector<std::string> messages = analyzer.GetLogMessages(); | 425 std::vector<std::string> messages = analyzer.GetLogMessages(); |
412 ASSERT_EQ(2U, messages.size()); | 426 ASSERT_EQ(2U, messages.size()); |
413 EXPECT_EQ("hello world", messages[0]); | 427 EXPECT_EQ("hello world", messages[0]); |
414 EXPECT_EQ("foo bar", messages[1]); | 428 EXPECT_EQ("foo bar", messages[1]); |
415 } | 429 } |
416 | 430 |
417 } // namespace debug | 431 } // namespace debug |
418 } // namespace base | 432 } // namespace base |
OLD | NEW |