Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(29)

Side by Side Diff: util/mac/process_reader_test.cc

Issue 543193002: Make ProcessReaderModule and ProcessReaderThread nested classes (Closed) Base URL: https://chromium.googlesource.com/crashpad/crashpad@master
Patch Set: Address review feedback Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « util/mac/process_reader.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « util/mac/process_reader.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698