| OLD | NEW |
| 1 // Copyright 2014 The Crashpad Authors. All rights reserved. | 1 // Copyright 2014 The Crashpad Authors. All rights reserved. |
| 2 // | 2 // |
| 3 // Licensed under the Apache License, Version 2.0 (the "License"); | 3 // Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 // you may not use this file except in compliance with the License. | 4 // you may not use this file except in compliance with the License. |
| 5 // You may obtain a copy of the License at | 5 // You may obtain a copy of the License at |
| 6 // | 6 // |
| 7 // http://www.apache.org/licenses/LICENSE-2.0 | 7 // http://www.apache.org/licenses/LICENSE-2.0 |
| 8 // | 8 // |
| 9 // Unless required by applicable law or agreed to in writing, software | 9 // Unless required by applicable law or agreed to in writing, software |
| 10 // distributed under the License is distributed on an "AS IS" BASIS, | 10 // distributed under the License is distributed on an "AS IS" BASIS, |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 137 uint64_t thread_id; | 137 uint64_t thread_id; |
| 138 int rv = pthread_threadid_np(pthread, &thread_id); | 138 int rv = pthread_threadid_np(pthread, &thread_id); |
| 139 CHECK_EQ(rv, 0); | 139 CHECK_EQ(rv, 0); |
| 140 return thread_id; | 140 return thread_id; |
| 141 } | 141 } |
| 142 | 142 |
| 143 TEST(ProcessReader, SelfOneThread) { | 143 TEST(ProcessReader, SelfOneThread) { |
| 144 ProcessReader process_reader; | 144 ProcessReader process_reader; |
| 145 ASSERT_TRUE(process_reader.Initialize(mach_task_self())); | 145 ASSERT_TRUE(process_reader.Initialize(mach_task_self())); |
| 146 | 146 |
| 147 const std::vector<ProcessReaderThread>& threads = process_reader.Threads(); | 147 const std::vector<ProcessReader::Thread>& threads = process_reader.Threads(); |
| 148 | 148 |
| 149 // If other tests ran in this process previously, threads may have been | 149 // If other tests ran in this process previously, threads may have been |
| 150 // created and may still be running. This check must look for at least one | 150 // created and may still be running. This check must look for at least one |
| 151 // thread, not exactly one thread. | 151 // thread, not exactly one thread. |
| 152 ASSERT_GE(threads.size(), 1u); | 152 ASSERT_GE(threads.size(), 1u); |
| 153 | 153 |
| 154 EXPECT_EQ(PthreadToThreadID(pthread_self()), threads[0].id); | 154 EXPECT_EQ(PthreadToThreadID(pthread_self()), threads[0].id); |
| 155 | 155 |
| 156 base::mac::ScopedMachSendRight thread_self(mach_thread_self()); | 156 base::mac::ScopedMachSendRight thread_self(mach_thread_self()); |
| 157 EXPECT_EQ(thread_self, threads[0].port); | 157 EXPECT_EQ(thread_self, threads[0].port); |
| (...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 308 | 308 |
| 309 typedef std::map<uint64_t, TestThreadPool::ThreadExpectation> ThreadMap; | 309 typedef std::map<uint64_t, TestThreadPool::ThreadExpectation> ThreadMap; |
| 310 | 310 |
| 311 // Verifies that all of the threads in |threads|, obtained from ProcessReader, | 311 // Verifies that all of the threads in |threads|, obtained from ProcessReader, |
| 312 // agree with the expectation in |thread_map|. If |tolerate_extra_threads| is | 312 // agree with the expectation in |thread_map|. If |tolerate_extra_threads| is |
| 313 // true, |threads| is allowed to contain threads that are not listed in | 313 // true, |threads| is allowed to contain threads that are not listed in |
| 314 // |thread_map|. This is useful when testing situations where code outside of | 314 // |thread_map|. This is useful when testing situations where code outside of |
| 315 // the test’s control (such as system libraries) may start threads, or may have | 315 // the test’s control (such as system libraries) may start threads, or may have |
| 316 // started threads prior to a test’s execution. | 316 // started threads prior to a test’s execution. |
| 317 void ExpectSeveralThreads(ThreadMap* thread_map, | 317 void ExpectSeveralThreads(ThreadMap* thread_map, |
| 318 const std::vector<ProcessReaderThread>& threads, | 318 const std::vector<ProcessReader::Thread>& threads, |
| 319 const bool tolerate_extra_threads) { | 319 const bool tolerate_extra_threads) { |
| 320 if (tolerate_extra_threads) { | 320 if (tolerate_extra_threads) { |
| 321 ASSERT_GE(threads.size(), thread_map->size()); | 321 ASSERT_GE(threads.size(), thread_map->size()); |
| 322 } else { | 322 } else { |
| 323 ASSERT_EQ(thread_map->size(), threads.size()); | 323 ASSERT_EQ(thread_map->size(), threads.size()); |
| 324 } | 324 } |
| 325 | 325 |
| 326 for (size_t thread_index = 0; thread_index < threads.size(); ++thread_index) { | 326 for (size_t thread_index = 0; thread_index < threads.size(); ++thread_index) { |
| 327 const ProcessReaderThread& thread = threads[thread_index]; | 327 const ProcessReader::Thread& thread = threads[thread_index]; |
| 328 mach_vm_address_t thread_stack_region_end = | 328 mach_vm_address_t thread_stack_region_end = |
| 329 thread.stack_region_address + thread.stack_region_size; | 329 thread.stack_region_address + thread.stack_region_size; |
| 330 | 330 |
| 331 const auto& iterator = thread_map->find(thread.id); | 331 const auto& iterator = thread_map->find(thread.id); |
| 332 if (!tolerate_extra_threads) { | 332 if (!tolerate_extra_threads) { |
| 333 // Make sure that the thread is in the expectation map. | 333 // Make sure that the thread is in the expectation map. |
| 334 ASSERT_NE(thread_map->end(), iterator); | 334 ASSERT_NE(thread_map->end(), iterator); |
| 335 } | 335 } |
| 336 | 336 |
| 337 if (iterator != thread_map->end()) { | 337 if (iterator != thread_map->end()) { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 350 // with any other thread’s. Each thread should have a unique value for its | 350 // with any other thread’s. Each thread should have a unique value for its |
| 351 // ID and port, and each should have its own stack that doesn’t touch any | 351 // ID and port, and each should have its own stack that doesn’t touch any |
| 352 // other thread’s stack. | 352 // other thread’s stack. |
| 353 for (size_t other_thread_index = 0; | 353 for (size_t other_thread_index = 0; |
| 354 other_thread_index < threads.size(); | 354 other_thread_index < threads.size(); |
| 355 ++other_thread_index) { | 355 ++other_thread_index) { |
| 356 if (thread_index == other_thread_index) { | 356 if (thread_index == other_thread_index) { |
| 357 continue; | 357 continue; |
| 358 } | 358 } |
| 359 | 359 |
| 360 const ProcessReaderThread& other_thread = threads[other_thread_index]; | 360 const ProcessReader::Thread& other_thread = threads[other_thread_index]; |
| 361 | 361 |
| 362 EXPECT_NE(thread.id, other_thread.id); | 362 EXPECT_NE(thread.id, other_thread.id); |
| 363 EXPECT_NE(thread.port, other_thread.port); | 363 EXPECT_NE(thread.port, other_thread.port); |
| 364 | 364 |
| 365 mach_vm_address_t other_thread_stack_region_end = | 365 mach_vm_address_t other_thread_stack_region_end = |
| 366 other_thread.stack_region_address + other_thread.stack_region_size; | 366 other_thread.stack_region_address + other_thread.stack_region_size; |
| 367 EXPECT_FALSE( | 367 EXPECT_FALSE( |
| 368 thread.stack_region_address >= other_thread.stack_region_address && | 368 thread.stack_region_address >= other_thread.stack_region_address && |
| 369 thread.stack_region_address < other_thread_stack_region_end); | 369 thread.stack_region_address < other_thread_stack_region_end); |
| 370 EXPECT_FALSE( | 370 EXPECT_FALSE( |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 402 thread_map[self_thread_id] = expectation; | 402 thread_map[self_thread_id] = expectation; |
| 403 for (size_t thread_index = 0; thread_index < kChildThreads; ++thread_index) { | 403 for (size_t thread_index = 0; thread_index < kChildThreads; ++thread_index) { |
| 404 uint64_t thread_id = thread_pool.GetThreadInfo(thread_index, &expectation); | 404 uint64_t thread_id = thread_pool.GetThreadInfo(thread_index, &expectation); |
| 405 | 405 |
| 406 // There can’t be any duplicate thread IDs. | 406 // There can’t be any duplicate thread IDs. |
| 407 EXPECT_EQ(0u, thread_map.count(thread_id)); | 407 EXPECT_EQ(0u, thread_map.count(thread_id)); |
| 408 | 408 |
| 409 thread_map[thread_id] = expectation; | 409 thread_map[thread_id] = expectation; |
| 410 } | 410 } |
| 411 | 411 |
| 412 const std::vector<ProcessReaderThread>& threads = process_reader.Threads(); | 412 const std::vector<ProcessReader::Thread>& threads = process_reader.Threads(); |
| 413 | 413 |
| 414 // Other tests that have run previously may have resulted in the creation of | 414 // Other tests that have run previously may have resulted in the creation of |
| 415 // threads that still exist, so pass true for |tolerate_extra_threads|. | 415 // threads that still exist, so pass true for |tolerate_extra_threads|. |
| 416 ExpectSeveralThreads(&thread_map, threads, true); | 416 ExpectSeveralThreads(&thread_map, threads, true); |
| 417 | 417 |
| 418 // When testing in-process, verify that when this thread shows up in the | 418 // When testing in-process, verify that when this thread shows up in the |
| 419 // vector, it has the expected thread port, and that this thread port only | 419 // vector, it has the expected thread port, and that this thread port only |
| 420 // shows up once. | 420 // shows up once. |
| 421 base::mac::ScopedMachSendRight thread_self(mach_thread_self()); | 421 base::mac::ScopedMachSendRight thread_self(mach_thread_self()); |
| 422 bool found_thread_self = false; | 422 bool found_thread_self = false; |
| 423 for (const ProcessReaderThread& thread : threads) { | 423 for (const ProcessReader::Thread& thread : threads) { |
| 424 if (thread.port == thread_self) { | 424 if (thread.port == thread_self) { |
| 425 EXPECT_FALSE(found_thread_self); | 425 EXPECT_FALSE(found_thread_self); |
| 426 found_thread_self = true; | 426 found_thread_self = true; |
| 427 EXPECT_EQ(self_thread_id, thread.id); | 427 EXPECT_EQ(self_thread_id, thread.id); |
| 428 } | 428 } |
| 429 } | 429 } |
| 430 EXPECT_TRUE(found_thread_self); | 430 EXPECT_TRUE(found_thread_self); |
| 431 } | 431 } |
| 432 | 432 |
| 433 class ProcessReaderThreadedChild final : public MachMultiprocess { | 433 class ProcessReaderThreadedChild final : public MachMultiprocess { |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 470 sizeof(expectation.suspend_count)); | 470 sizeof(expectation.suspend_count)); |
| 471 ASSERT_EQ(static_cast<ssize_t>(sizeof(expectation.suspend_count)), rv) | 471 ASSERT_EQ(static_cast<ssize_t>(sizeof(expectation.suspend_count)), rv) |
| 472 << ErrnoMessage("read"); | 472 << ErrnoMessage("read"); |
| 473 | 473 |
| 474 // There can’t be any duplicate thread IDs. | 474 // There can’t be any duplicate thread IDs. |
| 475 EXPECT_EQ(0u, thread_map.count(thread_id)); | 475 EXPECT_EQ(0u, thread_map.count(thread_id)); |
| 476 | 476 |
| 477 thread_map[thread_id] = expectation; | 477 thread_map[thread_id] = expectation; |
| 478 } | 478 } |
| 479 | 479 |
| 480 const std::vector<ProcessReaderThread>& threads = process_reader.Threads(); | 480 const std::vector<ProcessReader::Thread>& threads = process_reader.Threads()
; |
| 481 | 481 |
| 482 // The child shouldn’t have any threads other than its main thread and the | 482 // The child shouldn’t have any threads other than its main thread and the |
| 483 // ones it created in its pool, so pass false for |tolerate_extra_threads|. | 483 // ones it created in its pool, so pass false for |tolerate_extra_threads|. |
| 484 ExpectSeveralThreads(&thread_map, threads, false); | 484 ExpectSeveralThreads(&thread_map, threads, false); |
| 485 | 485 |
| 486 // Tell the child that it’s OK to exit. The child needed to be kept alive | 486 // Tell the child that it’s OK to exit. The child needed to be kept alive |
| 487 // until the parent finished working with it. | 487 // until the parent finished working with it. |
| 488 int write_fd = WritePipeFD(); | 488 int write_fd = WritePipeFD(); |
| 489 char c = '\0'; | 489 char c = '\0'; |
| 490 ssize_t rv = WriteFD(write_fd, &c, 1); | 490 ssize_t rv = WriteFD(write_fd, &c, 1); |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 571 const size_t kChildThreads = 64; | 571 const size_t kChildThreads = 64; |
| 572 ProcessReaderThreadedChild process_reader_threaded_child(kChildThreads); | 572 ProcessReaderThreadedChild process_reader_threaded_child(kChildThreads); |
| 573 process_reader_threaded_child.Run(); | 573 process_reader_threaded_child.Run(); |
| 574 } | 574 } |
| 575 | 575 |
| 576 TEST(ProcessReader, SelfModules) { | 576 TEST(ProcessReader, SelfModules) { |
| 577 ProcessReader process_reader; | 577 ProcessReader process_reader; |
| 578 ASSERT_TRUE(process_reader.Initialize(mach_task_self())); | 578 ASSERT_TRUE(process_reader.Initialize(mach_task_self())); |
| 579 | 579 |
| 580 uint32_t dyld_image_count = _dyld_image_count(); | 580 uint32_t dyld_image_count = _dyld_image_count(); |
| 581 const std::vector<ProcessReaderModule>& modules = process_reader.Modules(); | 581 const std::vector<ProcessReader::Module>& modules = process_reader.Modules(); |
| 582 | 582 |
| 583 // There needs to be at least an entry for the main executable, for a dylib, | 583 // There needs to be at least an entry for the main executable, for a dylib, |
| 584 // and for dyld. | 584 // and for dyld. |
| 585 ASSERT_GE(modules.size(), 3u); | 585 ASSERT_GE(modules.size(), 3u); |
| 586 | 586 |
| 587 // dyld_image_count doesn’t include an entry for dyld itself, but |modules| | 587 // dyld_image_count doesn’t include an entry for dyld itself, but |modules| |
| 588 // does. | 588 // does. |
| 589 ASSERT_EQ(dyld_image_count + 1, modules.size()); | 589 ASSERT_EQ(dyld_image_count + 1, modules.size()); |
| 590 | 590 |
| 591 for (uint32_t index = 0; index < dyld_image_count; ++index) { | 591 for (uint32_t index = 0; index < dyld_image_count; ++index) { |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 632 public: | 632 public: |
| 633 ProcessReaderModulesChild() : MachMultiprocess() {} | 633 ProcessReaderModulesChild() : MachMultiprocess() {} |
| 634 | 634 |
| 635 ~ProcessReaderModulesChild() {} | 635 ~ProcessReaderModulesChild() {} |
| 636 | 636 |
| 637 private: | 637 private: |
| 638 void MachMultiprocessParent() override { | 638 void MachMultiprocessParent() override { |
| 639 ProcessReader process_reader; | 639 ProcessReader process_reader; |
| 640 ASSERT_TRUE(process_reader.Initialize(ChildTask())); | 640 ASSERT_TRUE(process_reader.Initialize(ChildTask())); |
| 641 | 641 |
| 642 const std::vector<ProcessReaderModule>& modules = process_reader.Modules(); | 642 const std::vector<ProcessReader::Module>& modules = |
| 643 process_reader.Modules(); |
| 643 | 644 |
| 644 // There needs to be at least an entry for the main executable, for a dylib, | 645 // There needs to be at least an entry for the main executable, for a dylib, |
| 645 // and for dyld. | 646 // and for dyld. |
| 646 ASSERT_GE(modules.size(), 3u); | 647 ASSERT_GE(modules.size(), 3u); |
| 647 | 648 |
| 648 int read_fd = ReadPipeFD(); | 649 int read_fd = ReadPipeFD(); |
| 649 | 650 |
| 650 uint32_t expect_modules; | 651 uint32_t expect_modules; |
| 651 ssize_t rv = ReadFD(read_fd, &expect_modules, sizeof(expect_modules)); | 652 ssize_t rv = ReadFD(read_fd, &expect_modules, sizeof(expect_modules)); |
| 652 ASSERT_EQ(static_cast<ssize_t>(sizeof(expect_modules)), rv) | 653 ASSERT_EQ(static_cast<ssize_t>(sizeof(expect_modules)), rv) |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 760 | 761 |
| 761 DISALLOW_COPY_AND_ASSIGN(ProcessReaderModulesChild); | 762 DISALLOW_COPY_AND_ASSIGN(ProcessReaderModulesChild); |
| 762 }; | 763 }; |
| 763 | 764 |
| 764 TEST(ProcessReader, ChildModules) { | 765 TEST(ProcessReader, ChildModules) { |
| 765 ProcessReaderModulesChild process_reader_modules_child; | 766 ProcessReaderModulesChild process_reader_modules_child; |
| 766 process_reader_modules_child.Run(); | 767 process_reader_modules_child.Run(); |
| 767 } | 768 } |
| 768 | 769 |
| 769 } // namespace | 770 } // namespace |
| OLD | NEW |