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_tracker.h" | 5 #include "base/debug/activity_tracker.h" |
6 | 6 |
7 #include <memory> | 7 #include <memory> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/files/file.h" | 10 #include "base/files/file.h" |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
83 size_t GetGlobalUserDataMemoryCacheUsed() { | 83 size_t GetGlobalUserDataMemoryCacheUsed() { |
84 return GlobalActivityTracker::Get()->user_data_allocator_.cache_used(); | 84 return GlobalActivityTracker::Get()->user_data_allocator_.cache_used(); |
85 } | 85 } |
86 | 86 |
87 void HandleProcessExit(int64_t id, | 87 void HandleProcessExit(int64_t id, |
88 int64_t stamp, | 88 int64_t stamp, |
89 int code, | 89 int code, |
90 GlobalActivityTracker::ProcessPhase phase, | 90 GlobalActivityTracker::ProcessPhase phase, |
91 std::string&& command, | 91 std::string&& command, |
92 ActivityUserData::Snapshot&& data) { | 92 ActivityUserData::Snapshot&& data) { |
93 exit_id = id; | 93 exit_id_ = id; |
94 exit_stamp = stamp; | 94 exit_stamp_ = stamp; |
95 exit_code = code; | 95 exit_code_ = code; |
96 exit_phase = phase; | 96 exit_phase_ = phase; |
97 exit_command = std::move(command); | 97 exit_command_ = std::move(command); |
98 exit_data = std::move(data); | 98 exit_data_ = std::move(data); |
99 } | 99 } |
100 | 100 |
101 static void DoNothing() {} | 101 static void DoNothing() {} |
102 | 102 |
103 int64_t exit_id = 0; | 103 int64_t exit_id_ = 0; |
104 int64_t exit_stamp; | 104 int64_t exit_stamp_; |
105 int exit_code; | 105 int exit_code_; |
106 GlobalActivityTracker::ProcessPhase exit_phase; | 106 GlobalActivityTracker::ProcessPhase exit_phase_; |
107 std::string exit_command; | 107 std::string exit_command_; |
108 ActivityUserData::Snapshot exit_data; | 108 ActivityUserData::Snapshot exit_data_; |
109 }; | 109 }; |
110 | 110 |
111 TEST_F(ActivityTrackerTest, UserDataTest) { | 111 TEST_F(ActivityTrackerTest, UserDataTest) { |
112 char buffer[256]; | 112 char buffer[256]; |
113 memset(buffer, 0, sizeof(buffer)); | 113 memset(buffer, 0, sizeof(buffer)); |
114 ActivityUserData data(buffer, sizeof(buffer)); | 114 ActivityUserData data(buffer, sizeof(buffer)); |
115 size_t space = sizeof(buffer) - sizeof(ActivityUserData::MemoryHeader); | 115 size_t space = sizeof(buffer) - sizeof(ActivityUserData::MemoryHeader); |
116 ASSERT_EQ(space, data.available_); | 116 ASSERT_EQ(space, data.available_); |
117 | 117 |
118 data.SetInt("foo", 1); | 118 data.SetInt("foo", 1); |
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
387 t2.WaitReady(); | 387 t2.WaitReady(); |
388 EXPECT_EQ(starting_active + 1, GetGlobalActiveTrackerCount()); | 388 EXPECT_EQ(starting_active + 1, GetGlobalActiveTrackerCount()); |
389 EXPECT_EQ(starting_inactive, GetGlobalInactiveTrackerCount()); | 389 EXPECT_EQ(starting_inactive, GetGlobalInactiveTrackerCount()); |
390 | 390 |
391 t2.Exit(); | 391 t2.Exit(); |
392 t2.Join(); | 392 t2.Join(); |
393 EXPECT_EQ(starting_active, GetGlobalActiveTrackerCount()); | 393 EXPECT_EQ(starting_active, GetGlobalActiveTrackerCount()); |
394 EXPECT_EQ(starting_inactive + 1, GetGlobalInactiveTrackerCount()); | 394 EXPECT_EQ(starting_inactive + 1, GetGlobalInactiveTrackerCount()); |
395 } | 395 } |
396 | 396 |
397 // This test fails roughly 10% of runs on Android tablets. | 397 TEST_F(ActivityTrackerTest, ProcessDeathTest) { |
398 // See http://crbug.com/723060 for details. | |
399 #if defined(OS_ANDROID) | |
400 #define MAYBE_ProcessDeathTest DISABLED_ProcessDeathTest | |
401 #else | |
402 #define MAYBE_ProcessDeathTest ProcessDeathTest | |
403 #endif | |
404 | |
405 TEST_F(ActivityTrackerTest, MAYBE_ProcessDeathTest) { | |
406 // This doesn't actually create and destroy a process. Instead, it uses for- | 398 // This doesn't actually create and destroy a process. Instead, it uses for- |
407 // testing interfaces to simulate data created by other processes. | 399 // testing interfaces to simulate data created by other processes. |
408 const ProcessId other_process_id = GetCurrentProcId() + 1; | 400 const ProcessId other_process_id = GetCurrentProcId() + 1; |
409 | 401 |
410 GlobalActivityTracker::CreateWithLocalMemory(kMemorySize, 0, "", 3, 0); | 402 GlobalActivityTracker::CreateWithLocalMemory(kMemorySize, 0, "", 3, 0); |
411 GlobalActivityTracker* global = GlobalActivityTracker::Get(); | 403 GlobalActivityTracker* global = GlobalActivityTracker::Get(); |
412 ThreadActivityTracker* thread = global->GetOrCreateTrackerForCurrentThread(); | 404 ThreadActivityTracker* thread = global->GetOrCreateTrackerForCurrentThread(); |
413 | 405 |
414 // Get callbacks for process exit. | 406 // Get callbacks for process exit. |
415 global->SetProcessExitCallback( | 407 global->SetProcessExitCallback( |
(...skipping 23 matching lines...) Expand all Loading... |
439 global->allocator()->GetAsReference( | 431 global->allocator()->GetAsReference( |
440 user_data.GetBaseAddress(), | 432 user_data.GetBaseAddress(), |
441 GlobalActivityTracker::kTypeIdUserDataRecord); | 433 GlobalActivityTracker::kTypeIdUserDataRecord); |
442 ASSERT_TRUE(user_data_ref); | 434 ASSERT_TRUE(user_data_ref); |
443 | 435 |
444 // Make a copy of the thread-tracker state so it can be restored later. | 436 // Make a copy of the thread-tracker state so it can be restored later. |
445 const size_t tracker_size = global->allocator()->GetAllocSize(tracker_ref); | 437 const size_t tracker_size = global->allocator()->GetAllocSize(tracker_ref); |
446 std::unique_ptr<char[]> tracker_copy(new char[tracker_size]); | 438 std::unique_ptr<char[]> tracker_copy(new char[tracker_size]); |
447 memcpy(tracker_copy.get(), thread->GetBaseAddress(), tracker_size); | 439 memcpy(tracker_copy.get(), thread->GetBaseAddress(), tracker_size); |
448 | 440 |
449 // Change the objects to appear to be owned by another process. | 441 // Change the objects to appear to be owned by another process. Use a "past" |
| 442 // time so that exit-time is always later than create-time. |
| 443 const int64_t past_stamp = Time::Now().ToInternalValue() - 1; |
450 int64_t owning_id; | 444 int64_t owning_id; |
451 int64_t stamp; | 445 int64_t stamp; |
452 ASSERT_TRUE(ActivityUserData::GetOwningProcessId( | 446 ASSERT_TRUE(ActivityUserData::GetOwningProcessId( |
453 global->process_data().GetBaseAddress(), &owning_id, &stamp)); | 447 global->process_data().GetBaseAddress(), &owning_id, &stamp)); |
454 EXPECT_NE(other_process_id, owning_id); | 448 EXPECT_NE(other_process_id, owning_id); |
455 ASSERT_TRUE(ThreadActivityTracker::GetOwningProcessId( | 449 ASSERT_TRUE(ThreadActivityTracker::GetOwningProcessId( |
456 thread->GetBaseAddress(), &owning_id, &stamp)); | 450 thread->GetBaseAddress(), &owning_id, &stamp)); |
457 EXPECT_NE(other_process_id, owning_id); | 451 EXPECT_NE(other_process_id, owning_id); |
458 ASSERT_TRUE(ActivityUserData::GetOwningProcessId(user_data.GetBaseAddress(), | 452 ASSERT_TRUE(ActivityUserData::GetOwningProcessId(user_data.GetBaseAddress(), |
459 &owning_id, &stamp)); | 453 &owning_id, &stamp)); |
460 EXPECT_NE(other_process_id, owning_id); | 454 EXPECT_NE(other_process_id, owning_id); |
461 global->process_data().SetOwningProcessIdForTesting(other_process_id, stamp); | 455 global->process_data().SetOwningProcessIdForTesting(other_process_id, |
462 thread->SetOwningProcessIdForTesting(other_process_id, stamp); | 456 past_stamp); |
463 user_data.SetOwningProcessIdForTesting(other_process_id, stamp); | 457 thread->SetOwningProcessIdForTesting(other_process_id, past_stamp); |
| 458 user_data.SetOwningProcessIdForTesting(other_process_id, past_stamp); |
464 ASSERT_TRUE(ActivityUserData::GetOwningProcessId( | 459 ASSERT_TRUE(ActivityUserData::GetOwningProcessId( |
465 global->process_data().GetBaseAddress(), &owning_id, &stamp)); | 460 global->process_data().GetBaseAddress(), &owning_id, &stamp)); |
466 EXPECT_EQ(other_process_id, owning_id); | 461 EXPECT_EQ(other_process_id, owning_id); |
467 ASSERT_TRUE(ThreadActivityTracker::GetOwningProcessId( | 462 ASSERT_TRUE(ThreadActivityTracker::GetOwningProcessId( |
468 thread->GetBaseAddress(), &owning_id, &stamp)); | 463 thread->GetBaseAddress(), &owning_id, &stamp)); |
469 EXPECT_EQ(other_process_id, owning_id); | 464 EXPECT_EQ(other_process_id, owning_id); |
470 ASSERT_TRUE(ActivityUserData::GetOwningProcessId(user_data.GetBaseAddress(), | 465 ASSERT_TRUE(ActivityUserData::GetOwningProcessId(user_data.GetBaseAddress(), |
471 &owning_id, &stamp)); | 466 &owning_id, &stamp)); |
472 EXPECT_EQ(other_process_id, owning_id); | 467 EXPECT_EQ(other_process_id, owning_id); |
473 | 468 |
474 // Check that process exit will perform callback and free the allocations. | 469 // Check that process exit will perform callback and free the allocations. |
475 ASSERT_EQ(0, exit_id); | 470 ASSERT_EQ(0, exit_id_); |
476 ASSERT_EQ(GlobalActivityTracker::kTypeIdProcessDataRecord, | 471 ASSERT_EQ(GlobalActivityTracker::kTypeIdProcessDataRecord, |
477 global->allocator()->GetType(proc_data_ref)); | 472 global->allocator()->GetType(proc_data_ref)); |
478 ASSERT_EQ(GlobalActivityTracker::kTypeIdActivityTracker, | 473 ASSERT_EQ(GlobalActivityTracker::kTypeIdActivityTracker, |
479 global->allocator()->GetType(tracker_ref)); | 474 global->allocator()->GetType(tracker_ref)); |
480 ASSERT_EQ(GlobalActivityTracker::kTypeIdUserDataRecord, | 475 ASSERT_EQ(GlobalActivityTracker::kTypeIdUserDataRecord, |
481 global->allocator()->GetType(user_data_ref)); | 476 global->allocator()->GetType(user_data_ref)); |
482 global->RecordProcessExit(other_process_id, 0); | 477 global->RecordProcessExit(other_process_id, 0); |
483 EXPECT_EQ(other_process_id, exit_id); | 478 EXPECT_EQ(other_process_id, exit_id_); |
484 EXPECT_EQ("foo --bar", exit_command); | 479 EXPECT_EQ("foo --bar", exit_command_); |
485 EXPECT_EQ(GlobalActivityTracker::kTypeIdProcessDataRecordFree, | 480 EXPECT_EQ(GlobalActivityTracker::kTypeIdProcessDataRecordFree, |
486 global->allocator()->GetType(proc_data_ref)); | 481 global->allocator()->GetType(proc_data_ref)); |
487 EXPECT_EQ(GlobalActivityTracker::kTypeIdActivityTrackerFree, | 482 EXPECT_EQ(GlobalActivityTracker::kTypeIdActivityTrackerFree, |
488 global->allocator()->GetType(tracker_ref)); | 483 global->allocator()->GetType(tracker_ref)); |
489 EXPECT_EQ(GlobalActivityTracker::kTypeIdUserDataRecordFree, | 484 EXPECT_EQ(GlobalActivityTracker::kTypeIdUserDataRecordFree, |
490 global->allocator()->GetType(user_data_ref)); | 485 global->allocator()->GetType(user_data_ref)); |
491 | 486 |
492 // Restore memory contents and types so things don't crash when doing real | 487 // Restore memory contents and types so things don't crash when doing real |
493 // process clean-up. | 488 // process clean-up. |
494 memcpy(const_cast<void*>(thread->GetBaseAddress()), tracker_copy.get(), | 489 memcpy(const_cast<void*>(thread->GetBaseAddress()), tracker_copy.get(), |
495 tracker_size); | 490 tracker_size); |
496 global->allocator()->ChangeType( | 491 global->allocator()->ChangeType( |
497 proc_data_ref, GlobalActivityTracker::kTypeIdProcessDataRecord, | 492 proc_data_ref, GlobalActivityTracker::kTypeIdProcessDataRecord, |
498 GlobalActivityTracker::kTypeIdUserDataRecordFree, false); | 493 GlobalActivityTracker::kTypeIdUserDataRecordFree, false); |
499 global->allocator()->ChangeType( | 494 global->allocator()->ChangeType( |
500 tracker_ref, GlobalActivityTracker::kTypeIdActivityTracker, | 495 tracker_ref, GlobalActivityTracker::kTypeIdActivityTracker, |
501 GlobalActivityTracker::kTypeIdActivityTrackerFree, false); | 496 GlobalActivityTracker::kTypeIdActivityTrackerFree, false); |
502 global->allocator()->ChangeType( | 497 global->allocator()->ChangeType( |
503 user_data_ref, GlobalActivityTracker::kTypeIdUserDataRecord, | 498 user_data_ref, GlobalActivityTracker::kTypeIdUserDataRecord, |
504 GlobalActivityTracker::kTypeIdUserDataRecordFree, false); | 499 GlobalActivityTracker::kTypeIdUserDataRecordFree, false); |
505 } | 500 } |
506 | 501 |
507 } // namespace debug | 502 } // namespace debug |
508 } // namespace base | 503 } // namespace base |
OLD | NEW |