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: snapshot/mac/process_reader_test.cc

Issue 880763002: Reorganize Multiprocess and implement for Windows (Closed) Base URL: https://chromium.googlesource.com/crashpad/crashpad@master
Patch Set: fixes 2 Created 5 years, 10 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 | « snapshot/mac/mach_o_image_annotations_reader_test.cc ('k') | util/file/file_io_win.cc » ('j') | 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 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
81 81
82 #if !defined(ARCH_CPU_64_BITS) 82 #if !defined(ARCH_CPU_64_BITS)
83 EXPECT_FALSE(process_reader.Is64Bit()); 83 EXPECT_FALSE(process_reader.Is64Bit());
84 #else 84 #else
85 EXPECT_TRUE(process_reader.Is64Bit()); 85 EXPECT_TRUE(process_reader.Is64Bit());
86 #endif 86 #endif
87 87
88 EXPECT_EQ(getpid(), process_reader.ParentProcessID()); 88 EXPECT_EQ(getpid(), process_reader.ParentProcessID());
89 EXPECT_EQ(ChildPID(), process_reader.ProcessID()); 89 EXPECT_EQ(ChildPID(), process_reader.ProcessID());
90 90
91 int read_fd = ReadPipeFD(); 91 FileHandle read_handle = ReadPipeHandle();
92 92
93 mach_vm_address_t address; 93 mach_vm_address_t address;
94 CheckedReadFile(read_fd, &address, sizeof(address)); 94 CheckedReadFile(read_handle, &address, sizeof(address));
95 95
96 std::string read_string; 96 std::string read_string;
97 ASSERT_TRUE(process_reader.Memory()->ReadCString(address, &read_string)); 97 ASSERT_TRUE(process_reader.Memory()->ReadCString(address, &read_string));
98 EXPECT_EQ(kTestMemory, read_string); 98 EXPECT_EQ(kTestMemory, read_string);
99 } 99 }
100 100
101 void MachMultiprocessChild() override { 101 void MachMultiprocessChild() override {
102 int write_fd = WritePipeFD(); 102 FileHandle write_handle = WritePipeHandle();
103 103
104 mach_vm_address_t address = 104 mach_vm_address_t address =
105 reinterpret_cast<mach_vm_address_t>(kTestMemory); 105 reinterpret_cast<mach_vm_address_t>(kTestMemory);
106 CheckedWriteFile(write_fd, &address, sizeof(address)); 106 CheckedWriteFile(write_handle, &address, sizeof(address));
107 107
108 // Wait for the parent to signal that it’s OK to exit by closing its end of 108 // Wait for the parent to signal that it’s OK to exit by closing its end of
109 // the pipe. 109 // the pipe.
110 CheckedReadFileAtEOF(ReadPipeFD()); 110 CheckedReadFileAtEOF(ReadPipeHandle());
111 } 111 }
112 112
113 DISALLOW_COPY_AND_ASSIGN(ProcessReaderChild); 113 DISALLOW_COPY_AND_ASSIGN(ProcessReaderChild);
114 }; 114 };
115 115
116 TEST(ProcessReader, ChildBasic) { 116 TEST(ProcessReader, ChildBasic) {
117 ProcessReaderChild process_reader_child; 117 ProcessReaderChild process_reader_child;
118 process_reader_child.Run(); 118 process_reader_child.Run();
119 } 119 }
120 120
(...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after
417 thread_count_(thread_count) { 417 thread_count_(thread_count) {
418 } 418 }
419 419
420 ~ProcessReaderThreadedChild() {} 420 ~ProcessReaderThreadedChild() {}
421 421
422 private: 422 private:
423 void MachMultiprocessParent() override { 423 void MachMultiprocessParent() override {
424 ProcessReader process_reader; 424 ProcessReader process_reader;
425 ASSERT_TRUE(process_reader.Initialize(ChildTask())); 425 ASSERT_TRUE(process_reader.Initialize(ChildTask()));
426 426
427 int read_fd = ReadPipeFD(); 427 FileHandle read_handle = ReadPipeHandle();
428 428
429 // Build a map of all expected threads, keyed by each thread’s ID, and with 429 // Build a map of all expected threads, keyed by each thread’s ID, and with
430 // addresses that should lie somewhere within each thread’s stack as values. 430 // addresses that should lie somewhere within each thread’s stack as values.
431 // These IDs and addresses all come from the child process via the pipe. 431 // These IDs and addresses all come from the child process via the pipe.
432 ThreadMap thread_map; 432 ThreadMap thread_map;
433 for (size_t thread_index = 0; 433 for (size_t thread_index = 0;
434 thread_index < thread_count_ + 1; 434 thread_index < thread_count_ + 1;
435 ++thread_index) { 435 ++thread_index) {
436 uint64_t thread_id; 436 uint64_t thread_id;
437 CheckedReadFile(read_fd, &thread_id, sizeof(thread_id)); 437 CheckedReadFile(read_handle, &thread_id, sizeof(thread_id));
438 438
439 TestThreadPool::ThreadExpectation expectation; 439 TestThreadPool::ThreadExpectation expectation;
440 CheckedReadFile(read_fd, 440 CheckedReadFile(read_handle,
441 &expectation.stack_address, 441 &expectation.stack_address,
442 sizeof(expectation.stack_address)); 442 sizeof(expectation.stack_address));
443 CheckedReadFile(read_fd, 443 CheckedReadFile(read_handle,
444 &expectation.suspend_count, 444 &expectation.suspend_count,
445 sizeof(expectation.suspend_count)); 445 sizeof(expectation.suspend_count));
446 446
447 // There can’t be any duplicate thread IDs. 447 // There can’t be any duplicate thread IDs.
448 EXPECT_EQ(0u, thread_map.count(thread_id)); 448 EXPECT_EQ(0u, thread_map.count(thread_id));
449 449
450 thread_map[thread_id] = expectation; 450 thread_map[thread_id] = expectation;
451 } 451 }
452 452
453 const std::vector<ProcessReader::Thread>& threads = process_reader.Threads() ; 453 const std::vector<ProcessReader::Thread>& threads = process_reader.Threads() ;
454 454
455 // The child shouldn’t have any threads other than its main thread and the 455 // The child shouldn’t have any threads other than its main thread and the
456 // ones it created in its pool, so pass false for |tolerate_extra_threads|. 456 // ones it created in its pool, so pass false for |tolerate_extra_threads|.
457 ExpectSeveralThreads(&thread_map, threads, false); 457 ExpectSeveralThreads(&thread_map, threads, false);
458 } 458 }
459 459
460 void MachMultiprocessChild() override { 460 void MachMultiprocessChild() override {
461 TestThreadPool thread_pool; 461 TestThreadPool thread_pool;
462 ASSERT_NO_FATAL_FAILURE(thread_pool.StartThreads(thread_count_)); 462 ASSERT_NO_FATAL_FAILURE(thread_pool.StartThreads(thread_count_));
463 463
464 int write_fd = WritePipeFD(); 464 FileHandle write_handle = WritePipeHandle();
465 465
466 // This thread isn’t part of the thread pool, but the parent will be able 466 // This thread isn’t part of the thread pool, but the parent will be able
467 // to inspect it. Write an entry for it. 467 // to inspect it. Write an entry for it.
468 uint64_t thread_id = PthreadToThreadID(pthread_self()); 468 uint64_t thread_id = PthreadToThreadID(pthread_self());
469 469
470 CheckedWriteFile(write_fd, &thread_id, sizeof(thread_id)); 470 CheckedWriteFile(write_handle, &thread_id, sizeof(thread_id));
471 471
472 TestThreadPool::ThreadExpectation expectation; 472 TestThreadPool::ThreadExpectation expectation;
473 expectation.stack_address = reinterpret_cast<mach_vm_address_t>(&thread_id); 473 expectation.stack_address = reinterpret_cast<mach_vm_address_t>(&thread_id);
474 expectation.suspend_count = 0; 474 expectation.suspend_count = 0;
475 475
476 CheckedWriteFile(write_fd, 476 CheckedWriteFile(write_handle,
477 &expectation.stack_address, 477 &expectation.stack_address,
478 sizeof(expectation.stack_address)); 478 sizeof(expectation.stack_address));
479 CheckedWriteFile(write_fd, 479 CheckedWriteFile(write_handle,
480 &expectation.suspend_count, 480 &expectation.suspend_count,
481 sizeof(expectation.suspend_count)); 481 sizeof(expectation.suspend_count));
482 482
483 // Write an entry for everything in the thread pool. 483 // Write an entry for everything in the thread pool.
484 for (size_t thread_index = 0; 484 for (size_t thread_index = 0;
485 thread_index < thread_count_; 485 thread_index < thread_count_;
486 ++thread_index) { 486 ++thread_index) {
487 uint64_t thread_id = 487 uint64_t thread_id =
488 thread_pool.GetThreadInfo(thread_index, &expectation); 488 thread_pool.GetThreadInfo(thread_index, &expectation);
489 489
490 CheckedWriteFile(write_fd, &thread_id, sizeof(thread_id)); 490 CheckedWriteFile(write_handle, &thread_id, sizeof(thread_id));
491 CheckedWriteFile(write_fd, 491 CheckedWriteFile(write_handle,
492 &expectation.stack_address, 492 &expectation.stack_address,
493 sizeof(expectation.stack_address)); 493 sizeof(expectation.stack_address));
494 CheckedWriteFile(write_fd, 494 CheckedWriteFile(write_handle,
495 &expectation.suspend_count, 495 &expectation.suspend_count,
496 sizeof(expectation.suspend_count)); 496 sizeof(expectation.suspend_count));
497 } 497 }
498 498
499 // Wait for the parent to signal that it’s OK to exit by closing its end of 499 // Wait for the parent to signal that it’s OK to exit by closing its end of
500 // the pipe. 500 // the pipe.
501 CheckedReadFileAtEOF(ReadPipeFD()); 501 CheckedReadFileAtEOF(ReadPipeHandle());
502 } 502 }
503 503
504 size_t thread_count_; 504 size_t thread_count_;
505 505
506 DISALLOW_COPY_AND_ASSIGN(ProcessReaderThreadedChild); 506 DISALLOW_COPY_AND_ASSIGN(ProcessReaderThreadedChild);
507 }; 507 };
508 508
509 TEST(ProcessReader, ChildOneThread) { 509 TEST(ProcessReader, ChildOneThread) {
510 // The main thread plus zero child threads equals one thread. 510 // The main thread plus zero child threads equals one thread.
511 const size_t kChildThreads = 0; 511 const size_t kChildThreads = 0;
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
587 ProcessReader process_reader; 587 ProcessReader process_reader;
588 ASSERT_TRUE(process_reader.Initialize(ChildTask())); 588 ASSERT_TRUE(process_reader.Initialize(ChildTask()));
589 589
590 const std::vector<ProcessReader::Module>& modules = 590 const std::vector<ProcessReader::Module>& modules =
591 process_reader.Modules(); 591 process_reader.Modules();
592 592
593 // There needs to be at least an entry for the main executable, for a dylib, 593 // There needs to be at least an entry for the main executable, for a dylib,
594 // and for dyld. 594 // and for dyld.
595 ASSERT_GE(modules.size(), 3u); 595 ASSERT_GE(modules.size(), 3u);
596 596
597 int read_fd = ReadPipeFD(); 597 FileHandle read_handle = ReadPipeHandle();
598 598
599 uint32_t expect_modules; 599 uint32_t expect_modules;
600 CheckedReadFile(read_fd, &expect_modules, sizeof(expect_modules)); 600 CheckedReadFile(read_handle, &expect_modules, sizeof(expect_modules));
601 601
602 ASSERT_EQ(expect_modules, modules.size()); 602 ASSERT_EQ(expect_modules, modules.size());
603 603
604 for (size_t index = 0; index < modules.size(); ++index) { 604 for (size_t index = 0; index < modules.size(); ++index) {
605 SCOPED_TRACE(base::StringPrintf( 605 SCOPED_TRACE(base::StringPrintf(
606 "index %zu, name %s", index, modules[index].name.c_str())); 606 "index %zu, name %s", index, modules[index].name.c_str()));
607 607
608 uint32_t expect_name_length; 608 uint32_t expect_name_length;
609 CheckedReadFile( 609 CheckedReadFile(
610 read_fd, &expect_name_length, sizeof(expect_name_length)); 610 read_handle, &expect_name_length, sizeof(expect_name_length));
611 611
612 // The NUL terminator is not read. 612 // The NUL terminator is not read.
613 std::string expect_name(expect_name_length, '\0'); 613 std::string expect_name(expect_name_length, '\0');
614 CheckedReadFile(read_fd, &expect_name[0], expect_name_length); 614 CheckedReadFile(read_handle, &expect_name[0], expect_name_length);
615 EXPECT_EQ(expect_name, modules[index].name); 615 EXPECT_EQ(expect_name, modules[index].name);
616 616
617 mach_vm_address_t expect_address; 617 mach_vm_address_t expect_address;
618 CheckedReadFile(read_fd, &expect_address, sizeof(expect_address)); 618 CheckedReadFile(read_handle, &expect_address, sizeof(expect_address));
619 EXPECT_EQ(expect_address, modules[index].reader->Address()); 619 EXPECT_EQ(expect_address, modules[index].reader->Address());
620 620
621 if (index == 0 || index == modules.size() - 1) { 621 if (index == 0 || index == modules.size() - 1) {
622 // dyld didn’t load the main executable or itself, so it couldn’t record 622 // dyld didn’t load the main executable or itself, so it couldn’t record
623 // these timestamps, and they are reported as 0. 623 // these timestamps, and they are reported as 0.
624 EXPECT_EQ(0, modules[index].timestamp); 624 EXPECT_EQ(0, modules[index].timestamp);
625 } else { 625 } else {
626 // Hope that the module didn’t change on disk. 626 // Hope that the module didn’t change on disk.
627 struct stat stat_buf; 627 struct stat stat_buf;
628 int rv = stat(expect_name.c_str(), &stat_buf); 628 int rv = stat(expect_name.c_str(), &stat_buf);
629 EXPECT_EQ(0, rv) << ErrnoMessage("stat"); 629 EXPECT_EQ(0, rv) << ErrnoMessage("stat");
630 if (rv == 0) { 630 if (rv == 0) {
631 EXPECT_EQ(stat_buf.st_mtime, modules[index].timestamp); 631 EXPECT_EQ(stat_buf.st_mtime, modules[index].timestamp);
632 } 632 }
633 } 633 }
634 } 634 }
635 } 635 }
636 636
637 void MachMultiprocessChild() override { 637 void MachMultiprocessChild() override {
638 int write_fd = WritePipeFD(); 638 FileHandle write_handle = WritePipeHandle();
639 639
640 uint32_t dyld_image_count = _dyld_image_count(); 640 uint32_t dyld_image_count = _dyld_image_count();
641 const struct dyld_all_image_infos* dyld_image_infos = 641 const struct dyld_all_image_infos* dyld_image_infos =
642 _dyld_get_all_image_infos(); 642 _dyld_get_all_image_infos();
643 643
644 uint32_t write_image_count = dyld_image_count; 644 uint32_t write_image_count = dyld_image_count;
645 if (dyld_image_infos->version >= 2) { 645 if (dyld_image_infos->version >= 2) {
646 // dyld_image_count doesn’t include an entry for dyld itself, but one will 646 // dyld_image_count doesn’t include an entry for dyld itself, but one will
647 // be written. 647 // be written.
648 ++write_image_count; 648 ++write_image_count;
649 } 649 }
650 650
651 CheckedWriteFile(write_fd, &write_image_count, sizeof(write_image_count)); 651 CheckedWriteFile(
652 write_handle, &write_image_count, sizeof(write_image_count));
652 653
653 for (size_t index = 0; index < write_image_count; ++index) { 654 for (size_t index = 0; index < write_image_count; ++index) {
654 const char* dyld_image_name; 655 const char* dyld_image_name;
655 mach_vm_address_t dyld_image_address; 656 mach_vm_address_t dyld_image_address;
656 657
657 if (index < dyld_image_count) { 658 if (index < dyld_image_count) {
658 dyld_image_name = _dyld_get_image_name(index); 659 dyld_image_name = _dyld_get_image_name(index);
659 dyld_image_address = 660 dyld_image_address =
660 reinterpret_cast<mach_vm_address_t>(_dyld_get_image_header(index)); 661 reinterpret_cast<mach_vm_address_t>(_dyld_get_image_header(index));
661 } else { 662 } else {
662 dyld_image_name = "/usr/lib/dyld"; 663 dyld_image_name = "/usr/lib/dyld";
663 dyld_image_address = reinterpret_cast<mach_vm_address_t>( 664 dyld_image_address = reinterpret_cast<mach_vm_address_t>(
664 dyld_image_infos->dyldImageLoadAddress); 665 dyld_image_infos->dyldImageLoadAddress);
665 } 666 }
666 667
667 uint32_t dyld_image_name_length = strlen(dyld_image_name); 668 uint32_t dyld_image_name_length = strlen(dyld_image_name);
668 CheckedWriteFile( 669 CheckedWriteFile(write_handle,
669 write_fd, &dyld_image_name_length, sizeof(dyld_image_name_length)); 670 &dyld_image_name_length,
671 sizeof(dyld_image_name_length));
670 672
671 // The NUL terminator is not written. 673 // The NUL terminator is not written.
672 CheckedWriteFile(write_fd, dyld_image_name, dyld_image_name_length); 674 CheckedWriteFile(write_handle, dyld_image_name, dyld_image_name_length);
673 675
674 CheckedWriteFile( 676 CheckedWriteFile(
675 write_fd, &dyld_image_address, sizeof(dyld_image_address)); 677 write_handle, &dyld_image_address, sizeof(dyld_image_address));
676 } 678 }
677 679
678 // Wait for the parent to signal that it’s OK to exit by closing its end of 680 // Wait for the parent to signal that it’s OK to exit by closing its end of
679 // the pipe. 681 // the pipe.
680 CheckedReadFileAtEOF(ReadPipeFD()); 682 CheckedReadFileAtEOF(ReadPipeHandle());
681 } 683 }
682 684
683 DISALLOW_COPY_AND_ASSIGN(ProcessReaderModulesChild); 685 DISALLOW_COPY_AND_ASSIGN(ProcessReaderModulesChild);
684 }; 686 };
685 687
686 TEST(ProcessReader, ChildModules) { 688 TEST(ProcessReader, ChildModules) {
687 ProcessReaderModulesChild process_reader_modules_child; 689 ProcessReaderModulesChild process_reader_modules_child;
688 process_reader_modules_child.Run(); 690 process_reader_modules_child.Run();
689 } 691 }
690 692
691 } // namespace 693 } // namespace
692 } // namespace test 694 } // namespace test
693 } // namespace crashpad 695 } // namespace crashpad
OLDNEW
« no previous file with comments | « snapshot/mac/mach_o_image_annotations_reader_test.cc ('k') | util/file/file_io_win.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698