| OLD | NEW |
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 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 "chrome/browser/conflicts/module_database_win.h" | 5 #include "chrome/browser/conflicts/module_database_win.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <memory> | 8 #include <memory> |
| 9 #include <vector> | 9 #include <vector> |
| 10 | 10 |
| 11 #include "base/bind.h" | 11 #include "base/bind.h" |
| 12 #include "base/memory/ptr_util.h" | 12 #include "base/memory/ptr_util.h" |
| 13 #include "base/message_loop/message_loop.h" | |
| 14 #include "base/run_loop.h" | 13 #include "base/run_loop.h" |
| 15 #include "base/strings/utf_string_conversions.h" | 14 #include "base/test/scoped_task_scheduler.h" |
| 15 #include "base/threading/sequenced_task_runner_handle.h" |
| 16 #include "base/threading/simple_thread.h" | 16 #include "base/threading/simple_thread.h" |
| 17 #include "testing/gtest/include/gtest/gtest.h" | 17 #include "testing/gtest/include/gtest/gtest.h" |
| 18 | 18 |
| 19 namespace { | 19 namespace { |
| 20 | 20 |
| 21 // A simple mechanism for running a single task on a separate thread. | 21 // A simple mechanism for running a single task on a separate thread. |
| 22 class SingleTaskRunner : public base::SimpleThread { | 22 class SingleTaskRunner : public base::SimpleThread { |
| 23 public: | 23 public: |
| 24 explicit SingleTaskRunner(base::Closure task) | 24 explicit SingleTaskRunner(base::Closure task) |
| 25 : base::SimpleThread("SingleTaskRunner"), task_(std::move(task)) {} | 25 : base::SimpleThread("SingleTaskRunner"), task_(std::move(task)) {} |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 73 using ModuleDatabase::InsertLoadAddress; | 73 using ModuleDatabase::InsertLoadAddress; |
| 74 using ModuleDatabase::RemoveLoadAddressById; | 74 using ModuleDatabase::RemoveLoadAddressById; |
| 75 using ModuleDatabase::RemoveLoadAddressByIndex; | 75 using ModuleDatabase::RemoveLoadAddressByIndex; |
| 76 }; | 76 }; |
| 77 | 77 |
| 78 class ModuleDatabaseTest : public testing::Test { | 78 class ModuleDatabaseTest : public testing::Test { |
| 79 protected: | 79 protected: |
| 80 ModuleDatabaseTest() | 80 ModuleDatabaseTest() |
| 81 : dll1_(kDll1), | 81 : dll1_(kDll1), |
| 82 dll2_(kDll2), | 82 dll2_(kDll2), |
| 83 message_loop_(base::MakeUnique<base::MessageLoop>()), | 83 module_database_(base::MakeUnique<ModuleDatabase>( |
| 84 module_database_( | 84 base::SequencedTaskRunnerHandle::Get())) {} |
| 85 base::MakeUnique<ModuleDatabase>(message_loop_->task_runner())) {} | |
| 86 | |
| 87 void RunLoopUntilIdle() { base::RunLoop().RunUntilIdle(); } | |
| 88 | 85 |
| 89 const ModuleDatabase::ModuleMap& modules() { | 86 const ModuleDatabase::ModuleMap& modules() { |
| 90 return module_database_->modules_; | 87 return module_database_->modules_; |
| 91 } | 88 } |
| 92 | 89 |
| 93 const ModuleDatabase::ProcessMap& processes() { | 90 const ModuleDatabase::ProcessMap& processes() { |
| 94 return module_database_->processes_; | 91 return module_database_->processes_; |
| 95 } | 92 } |
| 96 | 93 |
| 94 ModuleDatabase* module_database() { return module_database_.get(); } |
| 95 |
| 97 static uint32_t ProcessTypeToBit(content::ProcessType process_type) { | 96 static uint32_t ProcessTypeToBit(content::ProcessType process_type) { |
| 98 return ModuleDatabase::ProcessTypeToBit(process_type); | 97 return ModuleDatabase::ProcessTypeToBit(process_type); |
| 99 } | 98 } |
| 100 | 99 |
| 101 // Counts the occurrences of the given |module_id| in the given collection of | 100 // Counts the occurrences of the given |module_id| in the given collection of |
| 102 // |load_addresses|. | 101 // |load_addresses|. |
| 103 static size_t ModuleIdCount( | 102 static size_t ModuleIdCount( |
| 104 ModuleId module_id, | 103 ModuleId module_id, |
| 105 const ModuleDatabase::ModuleLoadAddresses& load_addresses) { | 104 const ModuleDatabase::ModuleLoadAddresses& load_addresses) { |
| 106 return std::count_if( | 105 return std::count_if( |
| 107 load_addresses.begin(), load_addresses.end(), | 106 load_addresses.begin(), load_addresses.end(), |
| 108 [module_id](const auto& x) { return module_id == x.first; }); | 107 [module_id](const auto& x) { return module_id == x.first; }); |
| 109 } | 108 } |
| 110 | 109 |
| 111 protected: | |
| 112 const base::FilePath dll1_; | 110 const base::FilePath dll1_; |
| 113 const base::FilePath dll2_; | 111 const base::FilePath dll2_; |
| 114 | 112 |
| 115 std::unique_ptr<base::MessageLoop> message_loop_; | 113 private: |
| 114 // Must be before |module_database_|. |
| 115 base::test::ScopedTaskScheduler scoped_task_scheduler_; |
| 116 |
| 116 std::unique_ptr<ModuleDatabase> module_database_; | 117 std::unique_ptr<ModuleDatabase> module_database_; |
| 117 | 118 |
| 118 private: | |
| 119 DISALLOW_COPY_AND_ASSIGN(ModuleDatabaseTest); | 119 DISALLOW_COPY_AND_ASSIGN(ModuleDatabaseTest); |
| 120 }; | 120 }; |
| 121 | 121 |
| 122 TEST_F(ModuleDatabaseTest, LoadAddressVectorOperations) { | 122 TEST_F(ModuleDatabaseTest, LoadAddressVectorOperations) { |
| 123 using TMD = TestModuleDatabase; | 123 using TMD = TestModuleDatabase; |
| 124 TestModuleDatabase::ModuleLoadAddresses la; | 124 TMD::ModuleLoadAddresses la; |
| 125 | 125 |
| 126 // Finds should fail in an empty collection. | 126 // Finds should fail in an empty collection. |
| 127 EXPECT_EQ(TMD::kInvalidIndex, TMD::FindLoadAddressIndexById(0, la)); | 127 EXPECT_EQ(TMD::kInvalidIndex, TMD::FindLoadAddressIndexById(0, la)); |
| 128 EXPECT_EQ(TMD::kInvalidIndex, TMD::FindLoadAddressIndexById(0x04000000, la)); | 128 EXPECT_EQ(TMD::kInvalidIndex, TMD::FindLoadAddressIndexById(0x04000000, la)); |
| 129 | 129 |
| 130 // A first insert should work. Don't start with ModuleId 0 so that later | 130 // A first insert should work. Don't start with ModuleId 0 so that later |
| 131 // inserts can insert that module. | 131 // inserts can insert that module. |
| 132 TMD::InsertLoadAddress(10, 0x04000000, &la); | 132 TMD::InsertLoadAddress(10, 0x04000000, &la); |
| 133 EXPECT_EQ(1u, la.size()); | 133 EXPECT_EQ(1u, la.size()); |
| 134 EXPECT_EQ(10, la[0].first); | 134 EXPECT_EQ(10, la[0].first); |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 263 EXPECT_EQ(10, la[0].first); | 263 EXPECT_EQ(10, la[0].first); |
| 264 EXPECT_EQ(0x04000000u, la[0].second); | 264 EXPECT_EQ(0x04000000u, la[0].second); |
| 265 | 265 |
| 266 // Remove the only remaining element. | 266 // Remove the only remaining element. |
| 267 TMD::RemoveLoadAddressByIndex(0, &la); | 267 TMD::RemoveLoadAddressByIndex(0, &la); |
| 268 EXPECT_TRUE(la.empty()); | 268 EXPECT_TRUE(la.empty()); |
| 269 } | 269 } |
| 270 | 270 |
| 271 TEST_F(ModuleDatabaseTest, LoadAddressVectorStressTest) { | 271 TEST_F(ModuleDatabaseTest, LoadAddressVectorStressTest) { |
| 272 using TMD = TestModuleDatabase; | 272 using TMD = TestModuleDatabase; |
| 273 TestModuleDatabase::ModuleLoadAddresses la; | 273 TMD::ModuleLoadAddresses la; |
| 274 | 274 |
| 275 for (size_t n = 1; n < 200; ++n) { | 275 for (size_t n = 1; n < 200; ++n) { |
| 276 // Will keep track of which elements have been inserted. | 276 // Will keep track of which elements have been inserted. |
| 277 std::vector<bool> inserted(n); | 277 std::vector<bool> inserted(n); |
| 278 size_t inserted_count = 0; | 278 size_t inserted_count = 0; |
| 279 | 279 |
| 280 // Generate a shuffled list of IDs. This will be the insertion order. | 280 // Generate a shuffled list of IDs. This will be the insertion order. |
| 281 // More insertions than elements will occur so that rewrites occur., | 281 // More insertions than elements will occur so that rewrites occur., |
| 282 std::vector<ModuleId> ids(11 * n / 10); | 282 std::vector<ModuleId> ids(11 * n / 10); |
| 283 for (size_t i = 0; i < 11 * n / 10; ++i) | 283 for (size_t i = 0; i < 11 * n / 10; ++i) |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 318 // Do the deletions. | 318 // Do the deletions. |
| 319 for (auto id : ids) { | 319 for (auto id : ids) { |
| 320 --inserted_count; | 320 --inserted_count; |
| 321 TMD::RemoveLoadAddressById(id, &la); | 321 TMD::RemoveLoadAddressById(id, &la); |
| 322 EXPECT_EQ(inserted_count, la.size()); | 322 EXPECT_EQ(inserted_count, la.size()); |
| 323 } | 323 } |
| 324 } | 324 } |
| 325 } | 325 } |
| 326 | 326 |
| 327 TEST_F(ModuleDatabaseTest, TasksAreBounced) { | 327 TEST_F(ModuleDatabaseTest, TasksAreBounced) { |
| 328 // Run a task on the current thread. This should not be bounced, so no | 328 // Run a task on the current thread. This should not be bounced, so their |
| 329 // task should be scheduled on the task runner. | 329 // results should be immediately available. |
| 330 module_database_->OnProcessStarted(kPid1, kCreateTime1, | 330 module_database()->OnProcessStarted(kPid1, kCreateTime1, |
| 331 content::PROCESS_TYPE_BROWSER); | 331 content::PROCESS_TYPE_BROWSER); |
| 332 EXPECT_TRUE(message_loop_->IsIdleForTesting()); | 332 EXPECT_EQ(1u, processes().size()); |
| 333 module_database_->OnModuleLoad(kPid1, kCreateTime1, dll1_, kSize1, kTime1, | 333 module_database()->OnModuleLoad(kPid1, kCreateTime1, dll1_, kSize1, kTime1, |
| 334 kGoodAddress1); | 334 kGoodAddress1); |
| 335 EXPECT_TRUE(message_loop_->IsIdleForTesting()); | 335 EXPECT_EQ(1u, modules().size()); |
| 336 module_database_->OnProcessEnded(kPid1, kCreateTime1); | 336 module_database()->OnProcessEnded(kPid1, kCreateTime1); |
| 337 EXPECT_TRUE(message_loop_->IsIdleForTesting()); | 337 EXPECT_EQ(0u, processes().size()); |
| 338 | 338 |
| 339 // Indicate another process start on this thread. This call can't be | 339 // Indicate another process start on this thread. This call can't be |
| 340 // bounced. | 340 // bounced. |
| 341 module_database_->OnProcessStarted(kPid2, kCreateTime2, | 341 module_database()->OnProcessStarted(kPid2, kCreateTime2, |
| 342 content::PROCESS_TYPE_BROWSER); | 342 content::PROCESS_TYPE_BROWSER); |
| 343 EXPECT_EQ(1u, processes().size()); |
| 343 | 344 |
| 344 // Run similar tasks on another thread. These should be bounced. | 345 // Run similar tasks on another thread with another module. These should be |
| 346 // bounced. |
| 345 RunTask(base::Bind(&ModuleDatabase::OnModuleLoad, | 347 RunTask(base::Bind(&ModuleDatabase::OnModuleLoad, |
| 346 base::Unretained(module_database_.get()), kPid2, | 348 base::Unretained(module_database()), kPid2, kCreateTime2, |
| 347 kCreateTime2, dll1_, kSize1, kTime1, kGoodAddress1)); | 349 dll2_, kSize1, kTime1, kGoodAddress1)); |
| 348 EXPECT_FALSE(message_loop_->IsIdleForTesting()); | 350 EXPECT_EQ(1u, modules().size()); |
| 349 RunLoopUntilIdle(); | 351 base::RunLoop().RunUntilIdle(); |
| 352 EXPECT_EQ(2u, modules().size()); |
| 350 | 353 |
| 351 RunTask(base::Bind(&ModuleDatabase::OnProcessEnded, | 354 RunTask(base::Bind(&ModuleDatabase::OnProcessEnded, |
| 352 base::Unretained(module_database_.get()), kPid2, | 355 base::Unretained(module_database()), kPid2, kCreateTime2)); |
| 353 kCreateTime2)); | 356 EXPECT_EQ(1u, processes().size()); |
| 354 EXPECT_FALSE(message_loop_->IsIdleForTesting()); | 357 base::RunLoop().RunUntilIdle(); |
| 355 RunLoopUntilIdle(); | 358 EXPECT_EQ(0u, processes().size()); |
| 356 } | 359 } |
| 357 | 360 |
| 358 TEST_F(ModuleDatabaseTest, EventsWithoutProcessIgnore) { | 361 TEST_F(ModuleDatabaseTest, EventsWithoutProcessIgnore) { |
| 359 EXPECT_EQ(0u, modules().size()); | 362 EXPECT_EQ(0u, modules().size()); |
| 360 EXPECT_EQ(0u, processes().size()); | 363 EXPECT_EQ(0u, processes().size()); |
| 361 | 364 |
| 362 module_database_->OnModuleLoad(kPid1, kCreateTime1, dll1_, kSize1, kTime1, | 365 module_database()->OnModuleLoad(kPid1, kCreateTime1, dll1_, kSize1, kTime1, |
| 363 kGoodAddress1); | 366 kGoodAddress1); |
| 364 | 367 |
| 365 EXPECT_EQ(0u, modules().size()); | 368 EXPECT_EQ(0u, modules().size()); |
| 366 EXPECT_EQ(0u, processes().size()); | 369 EXPECT_EQ(0u, processes().size()); |
| 367 } | 370 } |
| 368 | 371 |
| 369 TEST_F(ModuleDatabaseTest, OrphanedUnloadIgnored) { | 372 TEST_F(ModuleDatabaseTest, OrphanedUnloadIgnored) { |
| 370 EXPECT_EQ(0u, modules().size()); | 373 EXPECT_EQ(0u, modules().size()); |
| 371 EXPECT_EQ(0u, processes().size()); | 374 EXPECT_EQ(0u, processes().size()); |
| 372 | 375 |
| 373 // Start a process. | 376 // Start a process. |
| 374 module_database_->OnProcessStarted(kPid1, kCreateTime1, | 377 module_database()->OnProcessStarted(kPid1, kCreateTime1, |
| 375 content::PROCESS_TYPE_BROWSER); | 378 content::PROCESS_TYPE_BROWSER); |
| 376 EXPECT_EQ(0u, modules().size()); | 379 EXPECT_EQ(0u, modules().size()); |
| 377 EXPECT_EQ(1u, processes().size()); | 380 EXPECT_EQ(1u, processes().size()); |
| 378 auto p1 = processes().begin(); | 381 auto p1 = processes().begin(); |
| 379 EXPECT_EQ(kPid1, p1->first.process_id); | 382 EXPECT_EQ(kPid1, p1->first.process_id); |
| 380 EXPECT_EQ(kCreateTime1, p1->first.creation_time); | 383 EXPECT_EQ(kCreateTime1, p1->first.creation_time); |
| 381 EXPECT_EQ(content::PROCESS_TYPE_BROWSER, p1->first.process_type); | 384 EXPECT_EQ(content::PROCESS_TYPE_BROWSER, p1->first.process_type); |
| 382 EXPECT_EQ(0u, p1->second.loaded_modules.size()); | 385 EXPECT_EQ(0u, p1->second.loaded_modules.size()); |
| 383 EXPECT_EQ(0u, p1->second.unloaded_modules.size()); | 386 EXPECT_EQ(0u, p1->second.unloaded_modules.size()); |
| 384 | 387 |
| 385 // Indicate a module unload. This should do nothing because there's no | 388 // Indicate a module unload. This should do nothing because there's no |
| 386 // corresponding module. | 389 // corresponding module. |
| 387 module_database_->OnModuleUnload(kPid1, kCreateTime1, kGoodAddress1); | 390 module_database()->OnModuleUnload(kPid1, kCreateTime1, kGoodAddress1); |
| 388 EXPECT_EQ(0u, modules().size()); | 391 EXPECT_EQ(0u, modules().size()); |
| 389 EXPECT_EQ(1u, processes().size()); | 392 EXPECT_EQ(1u, processes().size()); |
| 390 EXPECT_EQ(0u, p1->second.loaded_modules.size()); | 393 EXPECT_EQ(0u, p1->second.loaded_modules.size()); |
| 391 EXPECT_EQ(0u, p1->second.unloaded_modules.size()); | 394 EXPECT_EQ(0u, p1->second.unloaded_modules.size()); |
| 392 } | 395 } |
| 393 | 396 |
| 394 TEST_F(ModuleDatabaseTest, DatabaseIsConsistent) { | 397 TEST_F(ModuleDatabaseTest, DatabaseIsConsistent) { |
| 395 EXPECT_EQ(0u, modules().size()); | 398 EXPECT_EQ(0u, modules().size()); |
| 396 EXPECT_EQ(0u, processes().size()); | 399 EXPECT_EQ(0u, processes().size()); |
| 397 | 400 |
| 398 // Start a process. | 401 // Start a process. |
| 399 module_database_->OnProcessStarted(kPid1, kCreateTime1, | 402 module_database()->OnProcessStarted(kPid1, kCreateTime1, |
| 400 content::PROCESS_TYPE_BROWSER); | 403 content::PROCESS_TYPE_BROWSER); |
| 401 EXPECT_EQ(0u, modules().size()); | 404 EXPECT_EQ(0u, modules().size()); |
| 402 EXPECT_EQ(1u, processes().size()); | 405 EXPECT_EQ(1u, processes().size()); |
| 403 auto p1 = processes().begin(); | 406 auto p1 = processes().begin(); |
| 404 EXPECT_EQ(kPid1, p1->first.process_id); | 407 EXPECT_EQ(kPid1, p1->first.process_id); |
| 405 EXPECT_EQ(kCreateTime1, p1->first.creation_time); | 408 EXPECT_EQ(kCreateTime1, p1->first.creation_time); |
| 406 EXPECT_EQ(content::PROCESS_TYPE_BROWSER, p1->first.process_type); | 409 EXPECT_EQ(content::PROCESS_TYPE_BROWSER, p1->first.process_type); |
| 407 EXPECT_EQ(0u, p1->second.loaded_modules.size()); | 410 EXPECT_EQ(0u, p1->second.loaded_modules.size()); |
| 408 EXPECT_EQ(0u, p1->second.unloaded_modules.size()); | 411 EXPECT_EQ(0u, p1->second.unloaded_modules.size()); |
| 409 | 412 |
| 410 // Load a module. | 413 // Load a module. |
| 411 module_database_->OnModuleLoad(kPid1, kCreateTime1, dll1_, kSize1, kTime1, | 414 module_database()->OnModuleLoad(kPid1, kCreateTime1, dll1_, kSize1, kTime1, |
| 412 kGoodAddress1); | 415 kGoodAddress1); |
| 413 EXPECT_EQ(1u, modules().size()); | 416 EXPECT_EQ(1u, modules().size()); |
| 414 EXPECT_EQ(1u, processes().size()); | 417 EXPECT_EQ(1u, processes().size()); |
| 415 | 418 |
| 416 // Ensure that the process and module sets are up to date. | 419 // Ensure that the process and module sets are up to date. |
| 417 auto m1 = modules().begin(); | 420 auto m1 = modules().begin(); |
| 418 EXPECT_EQ(dll1_, m1->first.module_path); | 421 EXPECT_EQ(dll1_, m1->first.module_path); |
| 419 EXPECT_EQ(ProcessTypeToBit(content::PROCESS_TYPE_BROWSER), | 422 EXPECT_EQ(ProcessTypeToBit(content::PROCESS_TYPE_BROWSER), |
| 420 m1->second.process_types); | 423 m1->second.process_types); |
| 421 EXPECT_EQ(kPid1, p1->first.process_id); | 424 EXPECT_EQ(kPid1, p1->first.process_id); |
| 422 EXPECT_EQ(kCreateTime1, p1->first.creation_time); | 425 EXPECT_EQ(kCreateTime1, p1->first.creation_time); |
| 423 EXPECT_EQ(content::PROCESS_TYPE_BROWSER, p1->first.process_type); | 426 EXPECT_EQ(content::PROCESS_TYPE_BROWSER, p1->first.process_type); |
| 424 EXPECT_EQ(1u, p1->second.loaded_modules.size()); | 427 EXPECT_EQ(1u, p1->second.loaded_modules.size()); |
| 425 EXPECT_EQ(0u, p1->second.unloaded_modules.size()); | 428 EXPECT_EQ(0u, p1->second.unloaded_modules.size()); |
| 426 EXPECT_EQ(1u, ModuleIdCount(m1->first.module_id, p1->second.loaded_modules)); | 429 EXPECT_EQ(1u, ModuleIdCount(m1->first.module_id, p1->second.loaded_modules)); |
| 427 | 430 |
| 428 // Provide a redundant load message for that module. | 431 // Provide a redundant load message for that module. |
| 429 module_database_->OnModuleLoad(kPid1, kCreateTime1, dll1_, kSize1, kTime1, | 432 module_database()->OnModuleLoad(kPid1, kCreateTime1, dll1_, kSize1, kTime1, |
| 430 kGoodAddress1); | 433 kGoodAddress1); |
| 431 EXPECT_EQ(1u, modules().size()); | 434 EXPECT_EQ(1u, modules().size()); |
| 432 EXPECT_EQ(1u, processes().size()); | 435 EXPECT_EQ(1u, processes().size()); |
| 433 | 436 |
| 434 // Ensure that the process and module sets haven't changed. | 437 // Ensure that the process and module sets haven't changed. |
| 435 EXPECT_EQ(dll1_, m1->first.module_path); | 438 EXPECT_EQ(dll1_, m1->first.module_path); |
| 436 EXPECT_EQ(ProcessTypeToBit(content::PROCESS_TYPE_BROWSER), | 439 EXPECT_EQ(ProcessTypeToBit(content::PROCESS_TYPE_BROWSER), |
| 437 m1->second.process_types); | 440 m1->second.process_types); |
| 438 EXPECT_EQ(kPid1, p1->first.process_id); | 441 EXPECT_EQ(kPid1, p1->first.process_id); |
| 439 EXPECT_EQ(kCreateTime1, p1->first.creation_time); | 442 EXPECT_EQ(kCreateTime1, p1->first.creation_time); |
| 440 EXPECT_EQ(content::PROCESS_TYPE_BROWSER, p1->first.process_type); | 443 EXPECT_EQ(content::PROCESS_TYPE_BROWSER, p1->first.process_type); |
| 441 EXPECT_EQ(1u, p1->second.loaded_modules.size()); | 444 EXPECT_EQ(1u, p1->second.loaded_modules.size()); |
| 442 EXPECT_EQ(0u, p1->second.unloaded_modules.size()); | 445 EXPECT_EQ(0u, p1->second.unloaded_modules.size()); |
| 443 EXPECT_EQ(1u, ModuleIdCount(m1->first.module_id, p1->second.loaded_modules)); | 446 EXPECT_EQ(1u, ModuleIdCount(m1->first.module_id, p1->second.loaded_modules)); |
| 444 | 447 |
| 445 // Load a second module into the process. | 448 // Load a second module into the process. |
| 446 module_database_->OnModuleLoad(kPid1, kCreateTime1, dll2_, kSize2, kTime2, | 449 module_database()->OnModuleLoad(kPid1, kCreateTime1, dll2_, kSize2, kTime2, |
| 447 kGoodAddress2); | 450 kGoodAddress2); |
| 448 EXPECT_EQ(2u, modules().size()); | 451 EXPECT_EQ(2u, modules().size()); |
| 449 EXPECT_EQ(1u, processes().size()); | 452 EXPECT_EQ(1u, processes().size()); |
| 450 | 453 |
| 451 // Ensure that the process and module sets are up to date. | 454 // Ensure that the process and module sets are up to date. |
| 452 auto m2 = modules().rbegin(); | 455 auto m2 = modules().rbegin(); |
| 453 EXPECT_EQ(dll2_, m2->first.module_path); | 456 EXPECT_EQ(dll2_, m2->first.module_path); |
| 454 EXPECT_EQ(ProcessTypeToBit(content::PROCESS_TYPE_BROWSER), | 457 EXPECT_EQ(ProcessTypeToBit(content::PROCESS_TYPE_BROWSER), |
| 455 m2->second.process_types); | 458 m2->second.process_types); |
| 456 EXPECT_EQ(kPid1, p1->first.process_id); | 459 EXPECT_EQ(kPid1, p1->first.process_id); |
| 457 EXPECT_EQ(kCreateTime1, p1->first.creation_time); | 460 EXPECT_EQ(kCreateTime1, p1->first.creation_time); |
| 458 EXPECT_EQ(content::PROCESS_TYPE_BROWSER, p1->first.process_type); | 461 EXPECT_EQ(content::PROCESS_TYPE_BROWSER, p1->first.process_type); |
| 459 EXPECT_EQ(2u, p1->second.loaded_modules.size()); | 462 EXPECT_EQ(2u, p1->second.loaded_modules.size()); |
| 460 EXPECT_EQ(0u, p1->second.unloaded_modules.size()); | 463 EXPECT_EQ(0u, p1->second.unloaded_modules.size()); |
| 461 EXPECT_EQ(1u, ModuleIdCount(m1->first.module_id, p1->second.loaded_modules)); | 464 EXPECT_EQ(1u, ModuleIdCount(m1->first.module_id, p1->second.loaded_modules)); |
| 462 EXPECT_EQ(1u, ModuleIdCount(m2->first.module_id, p1->second.loaded_modules)); | 465 EXPECT_EQ(1u, ModuleIdCount(m2->first.module_id, p1->second.loaded_modules)); |
| 463 | 466 |
| 464 // Unload the second module. | 467 // Unload the second module. |
| 465 module_database_->OnModuleUnload(kPid1, kCreateTime1, kGoodAddress2); | 468 module_database()->OnModuleUnload(kPid1, kCreateTime1, kGoodAddress2); |
| 466 EXPECT_EQ(2u, modules().size()); | 469 EXPECT_EQ(2u, modules().size()); |
| 467 EXPECT_EQ(1u, processes().size()); | 470 EXPECT_EQ(1u, processes().size()); |
| 468 | 471 |
| 469 // Ensure that the process and module sets are up to date. | 472 // Ensure that the process and module sets are up to date. |
| 470 EXPECT_EQ(dll2_, m2->first.module_path); | 473 EXPECT_EQ(dll2_, m2->first.module_path); |
| 471 EXPECT_EQ(ProcessTypeToBit(content::PROCESS_TYPE_BROWSER), | 474 EXPECT_EQ(ProcessTypeToBit(content::PROCESS_TYPE_BROWSER), |
| 472 m2->second.process_types); | 475 m2->second.process_types); |
| 473 EXPECT_EQ(kPid1, p1->first.process_id); | 476 EXPECT_EQ(kPid1, p1->first.process_id); |
| 474 EXPECT_EQ(kCreateTime1, p1->first.creation_time); | 477 EXPECT_EQ(kCreateTime1, p1->first.creation_time); |
| 475 EXPECT_EQ(content::PROCESS_TYPE_BROWSER, p1->first.process_type); | 478 EXPECT_EQ(content::PROCESS_TYPE_BROWSER, p1->first.process_type); |
| 476 EXPECT_EQ(1u, p1->second.loaded_modules.size()); | 479 EXPECT_EQ(1u, p1->second.loaded_modules.size()); |
| 477 EXPECT_EQ(1u, p1->second.unloaded_modules.size()); | 480 EXPECT_EQ(1u, p1->second.unloaded_modules.size()); |
| 478 EXPECT_EQ(1u, ModuleIdCount(m1->first.module_id, p1->second.loaded_modules)); | 481 EXPECT_EQ(1u, ModuleIdCount(m1->first.module_id, p1->second.loaded_modules)); |
| 479 EXPECT_EQ(1u, | 482 EXPECT_EQ(1u, |
| 480 ModuleIdCount(m2->first.module_id, p1->second.unloaded_modules)); | 483 ModuleIdCount(m2->first.module_id, p1->second.unloaded_modules)); |
| 481 | 484 |
| 482 // Start a process. | 485 // Start a process. |
| 483 module_database_->OnProcessStarted(kPid2, kCreateTime2, | 486 module_database()->OnProcessStarted(kPid2, kCreateTime2, |
| 484 content::PROCESS_TYPE_RENDERER); | 487 content::PROCESS_TYPE_RENDERER); |
| 485 EXPECT_EQ(2u, modules().size()); | 488 EXPECT_EQ(2u, modules().size()); |
| 486 EXPECT_EQ(2u, processes().size()); | 489 EXPECT_EQ(2u, processes().size()); |
| 487 auto p2 = processes().rbegin(); | 490 auto p2 = processes().rbegin(); |
| 488 EXPECT_EQ(kPid2, p2->first.process_id); | 491 EXPECT_EQ(kPid2, p2->first.process_id); |
| 489 EXPECT_EQ(kCreateTime2, p2->first.creation_time); | 492 EXPECT_EQ(kCreateTime2, p2->first.creation_time); |
| 490 EXPECT_EQ(content::PROCESS_TYPE_RENDERER, p2->first.process_type); | 493 EXPECT_EQ(content::PROCESS_TYPE_RENDERER, p2->first.process_type); |
| 491 EXPECT_EQ(0u, p2->second.loaded_modules.size()); | 494 EXPECT_EQ(0u, p2->second.loaded_modules.size()); |
| 492 EXPECT_EQ(0u, p2->second.unloaded_modules.size()); | 495 EXPECT_EQ(0u, p2->second.unloaded_modules.size()); |
| 493 | 496 |
| 494 // Load the dummy.dll in the second process as well. | 497 // Load the dummy.dll in the second process as well. |
| 495 module_database_->OnModuleLoad(kPid2, kCreateTime2, dll1_, kSize1, kTime1, | 498 module_database()->OnModuleLoad(kPid2, kCreateTime2, dll1_, kSize1, kTime1, |
| 496 kGoodAddress1); | 499 kGoodAddress1); |
| 497 EXPECT_EQ(ProcessTypeToBit(content::PROCESS_TYPE_BROWSER) | | 500 EXPECT_EQ(ProcessTypeToBit(content::PROCESS_TYPE_BROWSER) | |
| 498 ProcessTypeToBit(content::PROCESS_TYPE_RENDERER), | 501 ProcessTypeToBit(content::PROCESS_TYPE_RENDERER), |
| 499 m1->second.process_types); | 502 m1->second.process_types); |
| 500 EXPECT_EQ(kPid2, p2->first.process_id); | 503 EXPECT_EQ(kPid2, p2->first.process_id); |
| 501 EXPECT_EQ(kCreateTime2, p2->first.creation_time); | 504 EXPECT_EQ(kCreateTime2, p2->first.creation_time); |
| 502 EXPECT_EQ(content::PROCESS_TYPE_RENDERER, p2->first.process_type); | 505 EXPECT_EQ(content::PROCESS_TYPE_RENDERER, p2->first.process_type); |
| 503 EXPECT_EQ(1u, p2->second.loaded_modules.size()); | 506 EXPECT_EQ(1u, p2->second.loaded_modules.size()); |
| 504 EXPECT_EQ(0u, p2->second.unloaded_modules.size()); | 507 EXPECT_EQ(0u, p2->second.unloaded_modules.size()); |
| 505 EXPECT_EQ(1u, ModuleIdCount(m1->first.module_id, p2->second.loaded_modules)); | 508 EXPECT_EQ(1u, ModuleIdCount(m1->first.module_id, p2->second.loaded_modules)); |
| 506 | 509 |
| 507 // End the second process without an explicit unload. This invalidates |p2|. | 510 // End the second process without an explicit unload. This invalidates |p2|. |
| 508 module_database_->OnProcessEnded(kPid2, kCreateTime2); | 511 module_database()->OnProcessEnded(kPid2, kCreateTime2); |
| 509 EXPECT_EQ(2u, modules().size()); | 512 EXPECT_EQ(2u, modules().size()); |
| 510 EXPECT_EQ(1u, processes().size()); | 513 EXPECT_EQ(1u, processes().size()); |
| 511 EXPECT_EQ(kPid1, p1->first.process_id); | 514 EXPECT_EQ(kPid1, p1->first.process_id); |
| 512 EXPECT_EQ(kCreateTime1, p1->first.creation_time); | 515 EXPECT_EQ(kCreateTime1, p1->first.creation_time); |
| 513 EXPECT_EQ(ProcessTypeToBit(content::PROCESS_TYPE_BROWSER) | | 516 EXPECT_EQ(ProcessTypeToBit(content::PROCESS_TYPE_BROWSER) | |
| 514 ProcessTypeToBit(content::PROCESS_TYPE_RENDERER), | 517 ProcessTypeToBit(content::PROCESS_TYPE_RENDERER), |
| 515 m1->second.process_types); | 518 m1->second.process_types); |
| 516 EXPECT_EQ(ProcessTypeToBit(content::PROCESS_TYPE_BROWSER), | 519 EXPECT_EQ(ProcessTypeToBit(content::PROCESS_TYPE_BROWSER), |
| 517 m2->second.process_types); | 520 m2->second.process_types); |
| 518 | 521 |
| 519 // End the first process without an explicit unload. This invalidates |p1|. | 522 // End the first process without an explicit unload. This invalidates |p1|. |
| 520 module_database_->OnProcessEnded(kPid1, kCreateTime1); | 523 module_database()->OnProcessEnded(kPid1, kCreateTime1); |
| 521 EXPECT_EQ(2u, modules().size()); | 524 EXPECT_EQ(2u, modules().size()); |
| 522 EXPECT_EQ(0u, processes().size()); | 525 EXPECT_EQ(0u, processes().size()); |
| 523 EXPECT_EQ(ProcessTypeToBit(content::PROCESS_TYPE_BROWSER) | | 526 EXPECT_EQ(ProcessTypeToBit(content::PROCESS_TYPE_BROWSER) | |
| 524 ProcessTypeToBit(content::PROCESS_TYPE_RENDERER), | 527 ProcessTypeToBit(content::PROCESS_TYPE_RENDERER), |
| 525 m1->second.process_types); | 528 m1->second.process_types); |
| 526 EXPECT_EQ(ProcessTypeToBit(content::PROCESS_TYPE_BROWSER), | 529 EXPECT_EQ(ProcessTypeToBit(content::PROCESS_TYPE_BROWSER), |
| 527 m2->second.process_types); | 530 m2->second.process_types); |
| 528 } | 531 } |
| OLD | NEW |