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 |