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 538 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
549 EXPECT_LE(sizeof(request), server.MachMessageServerRequestSize()); | 549 EXPECT_LE(sizeof(request), server.MachMessageServerRequestSize()); |
550 request.InitializeForTesting(); | 550 request.InitializeForTesting(); |
551 | 551 |
552 ExceptionRaiseReply reply; | 552 ExceptionRaiseReply reply; |
553 EXPECT_LE(sizeof(reply), server.MachMessageServerReplySize()); | 553 EXPECT_LE(sizeof(reply), server.MachMessageServerReplySize()); |
554 reply.InitializeForTesting(); | 554 reply.InitializeForTesting(); |
555 | 555 |
556 const exception_behavior_t kExceptionBehavior = EXCEPTION_DEFAULT; | 556 const exception_behavior_t kExceptionBehavior = EXCEPTION_DEFAULT; |
557 | 557 |
558 EXPECT_CALL(server, | 558 EXPECT_CALL(server, |
559 MockCatchMachException( | 559 MockCatchMachException(kExceptionBehavior, |
560 kExceptionBehavior, | 560 kServerLocalPort, |
561 kServerLocalPort, | 561 kExceptionThreadPort, |
562 kExceptionThreadPort, | 562 kExceptionTaskPort, |
563 kExceptionTaskPort, | 563 kExceptionType, |
564 kExceptionType, | 564 AreExceptionCodes(kTestExceptonCodes[0], |
565 AreExceptionCodes( | 565 kTestExceptonCodes[1]), |
566 kTestExceptonCodes[0], kTestExceptonCodes[1]), | 566 Pointee(Eq(THREAD_STATE_NONE)), |
567 Pointee(Eq(THREAD_STATE_NONE)), | 567 IsThreadStateCount(0u), |
568 IsThreadStateCount(0u), | 568 IsThreadStateCount(0u))) |
569 IsThreadStateCount(0u))) | |
570 .WillOnce(Return(KERN_SUCCESS)) | 569 .WillOnce(Return(KERN_SUCCESS)) |
571 .RetiresOnSaturation(); | 570 .RetiresOnSaturation(); |
572 | 571 |
573 bool destroy_complex_request = false; | 572 bool destroy_complex_request = false; |
574 EXPECT_TRUE(server.MachMessageServerFunction( | 573 EXPECT_TRUE(server.MachMessageServerFunction( |
575 reinterpret_cast<mach_msg_header_t*>(&request), | 574 reinterpret_cast<mach_msg_header_t*>(&request), |
576 reinterpret_cast<mach_msg_header_t*>(&reply), | 575 reinterpret_cast<mach_msg_header_t*>(&reply), |
577 &destroy_complex_request)); | 576 &destroy_complex_request)); |
578 EXPECT_TRUE(destroy_complex_request); | 577 EXPECT_TRUE(destroy_complex_request); |
579 | 578 |
580 reply.Verify(kExceptionBehavior); | 579 reply.Verify(kExceptionBehavior); |
581 } | 580 } |
582 | 581 |
583 TEST(ExcServerVariants, MockExceptionRaiseState) { | 582 TEST(ExcServerVariants, MockExceptionRaiseState) { |
584 ScopedDefaultValue<kern_return_t> default_kern_return_t(KERN_FAILURE); | 583 ScopedDefaultValue<kern_return_t> default_kern_return_t(KERN_FAILURE); |
585 | 584 |
586 MockUniversalMachExcServer server; | 585 MockUniversalMachExcServer server; |
587 | 586 |
588 ExceptionRaiseStateRequest request; | 587 ExceptionRaiseStateRequest request; |
589 EXPECT_LE(sizeof(request), server.MachMessageServerRequestSize()); | 588 EXPECT_LE(sizeof(request), server.MachMessageServerRequestSize()); |
590 request.InitializeForTesting(); | 589 request.InitializeForTesting(); |
591 | 590 |
592 ExceptionRaiseStateReply reply; | 591 ExceptionRaiseStateReply reply; |
593 EXPECT_LE(sizeof(reply), server.MachMessageServerReplySize()); | 592 EXPECT_LE(sizeof(reply), server.MachMessageServerReplySize()); |
594 reply.InitializeForTesting(); | 593 reply.InitializeForTesting(); |
595 | 594 |
596 const exception_behavior_t kExceptionBehavior = EXCEPTION_STATE; | 595 const exception_behavior_t kExceptionBehavior = EXCEPTION_STATE; |
597 | 596 |
598 EXPECT_CALL(server, | 597 EXPECT_CALL( |
599 MockCatchMachException( | 598 server, |
600 kExceptionBehavior, | 599 MockCatchMachException( |
601 kServerLocalPort, | 600 kExceptionBehavior, |
602 MACH_PORT_NULL, | 601 kServerLocalPort, |
603 MACH_PORT_NULL, | 602 MACH_PORT_NULL, |
604 kExceptionType, | 603 MACH_PORT_NULL, |
605 AreExceptionCodes( | 604 kExceptionType, |
606 kTestExceptonCodes[0], kTestExceptonCodes[1]), | 605 AreExceptionCodes(kTestExceptonCodes[0], kTestExceptonCodes[1]), |
607 Pointee(Eq(kThreadStateFlavor)), | 606 Pointee(Eq(kThreadStateFlavor)), |
608 IsThreadStateCount(kThreadStateFlavorCount), | 607 IsThreadStateCount(kThreadStateFlavorCount), |
609 IsThreadStateCount(arraysize(reply.new_state)))) | 608 IsThreadStateCount(arraysize(reply.new_state)))) |
610 .WillOnce(Return(KERN_SUCCESS)) | 609 .WillOnce(Return(KERN_SUCCESS)) |
611 .RetiresOnSaturation(); | 610 .RetiresOnSaturation(); |
612 | 611 |
613 bool destroy_complex_request = false; | 612 bool destroy_complex_request = false; |
614 EXPECT_TRUE(server.MachMessageServerFunction( | 613 EXPECT_TRUE(server.MachMessageServerFunction( |
615 reinterpret_cast<mach_msg_header_t*>(&request), | 614 reinterpret_cast<mach_msg_header_t*>(&request), |
616 reinterpret_cast<mach_msg_header_t*>(&reply), | 615 reinterpret_cast<mach_msg_header_t*>(&reply), |
617 &destroy_complex_request)); | 616 &destroy_complex_request)); |
618 | 617 |
619 // The request wasn’t complex, so nothing got a chance to change the value of | 618 // The request wasn’t complex, so nothing got a chance to change the value of |
(...skipping 11 matching lines...) Expand all Loading... |
631 ExceptionRaiseStateIdentityRequest request; | 630 ExceptionRaiseStateIdentityRequest request; |
632 EXPECT_LE(sizeof(request), server.MachMessageServerRequestSize()); | 631 EXPECT_LE(sizeof(request), server.MachMessageServerRequestSize()); |
633 request.InitializeForTesting(); | 632 request.InitializeForTesting(); |
634 | 633 |
635 ExceptionRaiseStateIdentityReply reply; | 634 ExceptionRaiseStateIdentityReply reply; |
636 EXPECT_LE(sizeof(reply), server.MachMessageServerReplySize()); | 635 EXPECT_LE(sizeof(reply), server.MachMessageServerReplySize()); |
637 reply.InitializeForTesting(); | 636 reply.InitializeForTesting(); |
638 | 637 |
639 const exception_behavior_t kExceptionBehavior = EXCEPTION_STATE_IDENTITY; | 638 const exception_behavior_t kExceptionBehavior = EXCEPTION_STATE_IDENTITY; |
640 | 639 |
641 EXPECT_CALL(server, | 640 EXPECT_CALL( |
642 MockCatchMachException( | 641 server, |
643 kExceptionBehavior, | 642 MockCatchMachException( |
644 kServerLocalPort, | 643 kExceptionBehavior, |
645 kExceptionThreadPort, | 644 kServerLocalPort, |
646 kExceptionTaskPort, | 645 kExceptionThreadPort, |
647 kExceptionType, | 646 kExceptionTaskPort, |
648 AreExceptionCodes( | 647 kExceptionType, |
649 kTestExceptonCodes[0], kTestExceptonCodes[1]), | 648 AreExceptionCodes(kTestExceptonCodes[0], kTestExceptonCodes[1]), |
650 Pointee(Eq(kThreadStateFlavor)), | 649 Pointee(Eq(kThreadStateFlavor)), |
651 IsThreadStateCount(kThreadStateFlavorCount), | 650 IsThreadStateCount(kThreadStateFlavorCount), |
652 IsThreadStateCount(arraysize(reply.new_state)))) | 651 IsThreadStateCount(arraysize(reply.new_state)))) |
653 .WillOnce(Return(KERN_SUCCESS)) | 652 .WillOnce(Return(KERN_SUCCESS)) |
654 .RetiresOnSaturation(); | 653 .RetiresOnSaturation(); |
655 | 654 |
656 bool destroy_complex_request = false; | 655 bool destroy_complex_request = false; |
657 EXPECT_TRUE(server.MachMessageServerFunction( | 656 EXPECT_TRUE(server.MachMessageServerFunction( |
658 reinterpret_cast<mach_msg_header_t*>(&request), | 657 reinterpret_cast<mach_msg_header_t*>(&request), |
659 reinterpret_cast<mach_msg_header_t*>(&reply), | 658 reinterpret_cast<mach_msg_header_t*>(&reply), |
660 &destroy_complex_request)); | 659 &destroy_complex_request)); |
661 EXPECT_TRUE(destroy_complex_request); | 660 EXPECT_TRUE(destroy_complex_request); |
662 | 661 |
(...skipping 11 matching lines...) Expand all Loading... |
674 | 673 |
675 MachExceptionRaiseReply reply; | 674 MachExceptionRaiseReply reply; |
676 EXPECT_LE(sizeof(reply), server.MachMessageServerReplySize()); | 675 EXPECT_LE(sizeof(reply), server.MachMessageServerReplySize()); |
677 reply.InitializeForTesting(); | 676 reply.InitializeForTesting(); |
678 | 677 |
679 const exception_behavior_t kExceptionBehavior = | 678 const exception_behavior_t kExceptionBehavior = |
680 EXCEPTION_DEFAULT | MACH_EXCEPTION_CODES; | 679 EXCEPTION_DEFAULT | MACH_EXCEPTION_CODES; |
681 | 680 |
682 EXPECT_CALL( | 681 EXPECT_CALL( |
683 server, | 682 server, |
684 MockCatchMachException( | 683 MockCatchMachException(kExceptionBehavior, |
685 kExceptionBehavior, | 684 kServerLocalPort, |
686 kServerLocalPort, | 685 kExceptionThreadPort, |
687 kExceptionThreadPort, | 686 kExceptionTaskPort, |
688 kExceptionTaskPort, | 687 kExceptionType, |
689 kExceptionType, | 688 AreExceptionCodes(kTestMachExceptionCodes[0], |
690 AreExceptionCodes( | 689 kTestMachExceptionCodes[1]), |
691 kTestMachExceptionCodes[0], kTestMachExceptionCodes[1]), | 690 Pointee(Eq(THREAD_STATE_NONE)), |
692 Pointee(Eq(THREAD_STATE_NONE)), | 691 IsThreadStateCount(0u), |
693 IsThreadStateCount(0u), | 692 IsThreadStateCount(0u))) |
694 IsThreadStateCount(0u))) | |
695 .WillOnce(Return(KERN_SUCCESS)) | 693 .WillOnce(Return(KERN_SUCCESS)) |
696 .RetiresOnSaturation(); | 694 .RetiresOnSaturation(); |
697 | 695 |
698 bool destroy_complex_request = false; | 696 bool destroy_complex_request = false; |
699 EXPECT_TRUE(server.MachMessageServerFunction( | 697 EXPECT_TRUE(server.MachMessageServerFunction( |
700 reinterpret_cast<mach_msg_header_t*>(&request), | 698 reinterpret_cast<mach_msg_header_t*>(&request), |
701 reinterpret_cast<mach_msg_header_t*>(&reply), | 699 reinterpret_cast<mach_msg_header_t*>(&reply), |
702 &destroy_complex_request)); | 700 &destroy_complex_request)); |
703 EXPECT_TRUE(destroy_complex_request); | 701 EXPECT_TRUE(destroy_complex_request); |
704 | 702 |
(...skipping 11 matching lines...) Expand all Loading... |
716 | 714 |
717 MachExceptionRaiseStateReply reply; | 715 MachExceptionRaiseStateReply reply; |
718 EXPECT_LE(sizeof(reply), server.MachMessageServerReplySize()); | 716 EXPECT_LE(sizeof(reply), server.MachMessageServerReplySize()); |
719 reply.InitializeForTesting(); | 717 reply.InitializeForTesting(); |
720 | 718 |
721 const exception_behavior_t kExceptionBehavior = | 719 const exception_behavior_t kExceptionBehavior = |
722 EXCEPTION_STATE | MACH_EXCEPTION_CODES; | 720 EXCEPTION_STATE | MACH_EXCEPTION_CODES; |
723 | 721 |
724 EXPECT_CALL( | 722 EXPECT_CALL( |
725 server, | 723 server, |
726 MockCatchMachException( | 724 MockCatchMachException(kExceptionBehavior, |
727 kExceptionBehavior, | 725 kServerLocalPort, |
728 kServerLocalPort, | 726 MACH_PORT_NULL, |
729 MACH_PORT_NULL, | 727 MACH_PORT_NULL, |
730 MACH_PORT_NULL, | 728 kExceptionType, |
731 kExceptionType, | 729 AreExceptionCodes(kTestMachExceptionCodes[0], |
732 AreExceptionCodes( | 730 kTestMachExceptionCodes[1]), |
733 kTestMachExceptionCodes[0], kTestMachExceptionCodes[1]), | 731 Pointee(Eq(kThreadStateFlavor)), |
734 Pointee(Eq(kThreadStateFlavor)), | 732 IsThreadStateCount(kThreadStateFlavorCount), |
735 IsThreadStateCount(kThreadStateFlavorCount), | 733 IsThreadStateCount(arraysize(reply.new_state)))) |
736 IsThreadStateCount(arraysize(reply.new_state)))) | |
737 .WillOnce(Return(KERN_SUCCESS)) | 734 .WillOnce(Return(KERN_SUCCESS)) |
738 .RetiresOnSaturation(); | 735 .RetiresOnSaturation(); |
739 | 736 |
740 bool destroy_complex_request = false; | 737 bool destroy_complex_request = false; |
741 EXPECT_TRUE(server.MachMessageServerFunction( | 738 EXPECT_TRUE(server.MachMessageServerFunction( |
742 reinterpret_cast<mach_msg_header_t*>(&request), | 739 reinterpret_cast<mach_msg_header_t*>(&request), |
743 reinterpret_cast<mach_msg_header_t*>(&reply), | 740 reinterpret_cast<mach_msg_header_t*>(&reply), |
744 &destroy_complex_request)); | 741 &destroy_complex_request)); |
745 | 742 |
746 // The request wasn’t complex, so nothing got a chance to change the value of | 743 // The request wasn’t complex, so nothing got a chance to change the value of |
(...skipping 14 matching lines...) Expand all Loading... |
761 | 758 |
762 MachExceptionRaiseStateIdentityReply reply; | 759 MachExceptionRaiseStateIdentityReply reply; |
763 EXPECT_LE(sizeof(reply), server.MachMessageServerReplySize()); | 760 EXPECT_LE(sizeof(reply), server.MachMessageServerReplySize()); |
764 reply.InitializeForTesting(); | 761 reply.InitializeForTesting(); |
765 | 762 |
766 const exception_behavior_t kExceptionBehavior = | 763 const exception_behavior_t kExceptionBehavior = |
767 EXCEPTION_STATE_IDENTITY | MACH_EXCEPTION_CODES; | 764 EXCEPTION_STATE_IDENTITY | MACH_EXCEPTION_CODES; |
768 | 765 |
769 EXPECT_CALL( | 766 EXPECT_CALL( |
770 server, | 767 server, |
771 MockCatchMachException( | 768 MockCatchMachException(kExceptionBehavior, |
772 kExceptionBehavior, | 769 kServerLocalPort, |
773 kServerLocalPort, | 770 kExceptionThreadPort, |
774 kExceptionThreadPort, | 771 kExceptionTaskPort, |
775 kExceptionTaskPort, | 772 kExceptionType, |
776 kExceptionType, | 773 AreExceptionCodes(kTestMachExceptionCodes[0], |
777 AreExceptionCodes( | 774 kTestMachExceptionCodes[1]), |
778 kTestMachExceptionCodes[0], kTestMachExceptionCodes[1]), | 775 Pointee(Eq(kThreadStateFlavor)), |
779 Pointee(Eq(kThreadStateFlavor)), | 776 IsThreadStateCount(kThreadStateFlavorCount), |
780 IsThreadStateCount(kThreadStateFlavorCount), | 777 IsThreadStateCount(arraysize(reply.new_state)))) |
781 IsThreadStateCount(arraysize(reply.new_state)))) | |
782 .WillOnce(Return(KERN_SUCCESS)) | 778 .WillOnce(Return(KERN_SUCCESS)) |
783 .RetiresOnSaturation(); | 779 .RetiresOnSaturation(); |
784 | 780 |
785 bool destroy_complex_request = false; | 781 bool destroy_complex_request = false; |
786 EXPECT_TRUE(server.MachMessageServerFunction( | 782 EXPECT_TRUE(server.MachMessageServerFunction( |
787 reinterpret_cast<mach_msg_header_t*>(&request), | 783 reinterpret_cast<mach_msg_header_t*>(&request), |
788 reinterpret_cast<mach_msg_header_t*>(&reply), | 784 reinterpret_cast<mach_msg_header_t*>(&reply), |
789 &destroy_complex_request)); | 785 &destroy_complex_request)); |
790 EXPECT_TRUE(destroy_complex_request); | 786 EXPECT_TRUE(destroy_complex_request); |
791 | 787 |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
863 public MachMultiprocess { | 859 public MachMultiprocess { |
864 public: | 860 public: |
865 TestExcServerVariants(exception_behavior_t behavior, | 861 TestExcServerVariants(exception_behavior_t behavior, |
866 thread_state_flavor_t flavor, | 862 thread_state_flavor_t flavor, |
867 mach_msg_type_number_t state_count) | 863 mach_msg_type_number_t state_count) |
868 : UniversalMachExcServer(), | 864 : UniversalMachExcServer(), |
869 MachMultiprocess(), | 865 MachMultiprocess(), |
870 behavior_(behavior), | 866 behavior_(behavior), |
871 flavor_(flavor), | 867 flavor_(flavor), |
872 state_count_(state_count), | 868 state_count_(state_count), |
873 handled_(false) { | 869 handled_(false) {} |
874 } | |
875 | 870 |
876 // UniversalMachExcServer: | 871 // UniversalMachExcServer: |
877 | 872 |
878 virtual kern_return_t CatchMachException( | 873 virtual kern_return_t CatchMachException( |
879 exception_behavior_t behavior, | 874 exception_behavior_t behavior, |
880 exception_handler_t exception_port, | 875 exception_handler_t exception_port, |
881 thread_t thread, | 876 thread_t thread, |
882 task_t task, | 877 task_t task, |
883 exception_type_t exception, | 878 exception_type_t exception, |
884 const mach_exception_data_type_t* code, | 879 const mach_exception_data_type_t* code, |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
929 *new_state_count); | 924 *new_state_count); |
930 EXPECT_NE(static_cast<natural_t*>(NULL), new_state); | 925 EXPECT_NE(static_cast<natural_t*>(NULL), new_state); |
931 } else { | 926 } else { |
932 EXPECT_EQ(THREAD_STATE_NONE, *flavor); | 927 EXPECT_EQ(THREAD_STATE_NONE, *flavor); |
933 EXPECT_EQ(0u, old_state_count); | 928 EXPECT_EQ(0u, old_state_count); |
934 EXPECT_EQ(NULL, old_state); | 929 EXPECT_EQ(NULL, old_state); |
935 EXPECT_EQ(0u, *new_state_count); | 930 EXPECT_EQ(0u, *new_state_count); |
936 EXPECT_EQ(NULL, new_state); | 931 EXPECT_EQ(NULL, new_state); |
937 } | 932 } |
938 | 933 |
939 // Even for an EXC_CRASH handler, returning KERN_SUCCESS with a | 934 return ExcServerSuccessfulReturnValue(behavior, false); |
940 // state-carrying reply will cause the kernel to try to set a new thread | |
941 // state, leading to a perceptible waste of time. Returning | |
942 // MACH_RCV_PORT_DIED is the only way to suppress this behavior while also | |
943 // preventing the kernel from looking for another (host-level) EXC_CRASH | |
944 // handler. See 10.9.4 xnu-2422.110.17/osfmk/kern/exception.c | |
945 // exception_triage(). | |
946 return has_state ? MACH_RCV_PORT_DIED : KERN_SUCCESS; | |
947 } | 935 } |
948 | 936 |
949 private: | 937 private: |
950 // MachMultiprocess: | 938 // MachMultiprocess: |
951 | 939 |
952 virtual void MachMultiprocessParent() override { | 940 virtual void MachMultiprocessParent() override { |
953 kern_return_t kr = MachMessageServer::Run(this, | 941 kern_return_t kr = MachMessageServer::Run(this, |
954 LocalPort(), | 942 LocalPort(), |
955 MACH_MSG_OPTION_NONE, | 943 MACH_MSG_OPTION_NONE, |
956 MachMessageServer::kOneShot, | 944 MachMessageServer::kOneShot, |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1050 // thread_get_state()) encounters an undersized buffer as reported by the | 1038 // thread_get_state()) encounters an undersized buffer as reported by the |
1051 // buffer size parameter, it returns KERN_INVALID_ARGUMENT, which causes | 1039 // buffer size parameter, it returns KERN_INVALID_ARGUMENT, which causes |
1052 // exception_deliver() to not actually deliver the exception and instead | 1040 // exception_deliver() to not actually deliver the exception and instead |
1053 // return that error code to exception_triage() as well. | 1041 // return that error code to exception_triage() as well. |
1054 // | 1042 // |
1055 // This bug is filed as radar 18312067. | 1043 // This bug is filed as radar 18312067. |
1056 // | 1044 // |
1057 // Additionaly, the AVX state flavors are also not tested because they’re | 1045 // Additionaly, the AVX state flavors are also not tested because they’re |
1058 // not available on all CPUs and OS versions. | 1046 // not available on all CPUs and OS versions. |
1059 #if defined(ARCH_CPU_X86) | 1047 #if defined(ARCH_CPU_X86) |
1060 { x86_THREAD_STATE32, x86_THREAD_STATE32_COUNT }, | 1048 {x86_THREAD_STATE32, x86_THREAD_STATE32_COUNT}, |
1061 { x86_FLOAT_STATE32, x86_FLOAT_STATE32_COUNT }, | 1049 {x86_FLOAT_STATE32, x86_FLOAT_STATE32_COUNT}, |
1062 { x86_EXCEPTION_STATE32, x86_EXCEPTION_STATE32_COUNT }, | 1050 {x86_EXCEPTION_STATE32, x86_EXCEPTION_STATE32_COUNT}, |
1063 #endif | 1051 #endif |
1064 #if defined(ARCH_CPU_X86_64) | 1052 #if defined(ARCH_CPU_X86_64) |
1065 { x86_THREAD_STATE64, x86_THREAD_STATE64_COUNT }, | 1053 {x86_THREAD_STATE64, x86_THREAD_STATE64_COUNT}, |
1066 { x86_FLOAT_STATE64, x86_FLOAT_STATE64_COUNT }, | 1054 {x86_FLOAT_STATE64, x86_FLOAT_STATE64_COUNT}, |
1067 { x86_EXCEPTION_STATE64, x86_EXCEPTION_STATE64_COUNT }, | 1055 {x86_EXCEPTION_STATE64, x86_EXCEPTION_STATE64_COUNT}, |
1068 #endif | 1056 #endif |
1069 { x86_THREAD_STATE, x86_THREAD_STATE_COUNT }, | 1057 {x86_THREAD_STATE, x86_THREAD_STATE_COUNT}, |
1070 { x86_FLOAT_STATE, x86_FLOAT_STATE_COUNT }, | 1058 {x86_FLOAT_STATE, x86_FLOAT_STATE_COUNT}, |
1071 { x86_EXCEPTION_STATE, x86_EXCEPTION_STATE_COUNT }, | 1059 {x86_EXCEPTION_STATE, x86_EXCEPTION_STATE_COUNT}, |
1072 #else | 1060 #else |
1073 #error Port this test to your CPU architecture. | 1061 #error Port this test to your CPU architecture. |
1074 #endif | 1062 #endif |
1075 }; | 1063 }; |
1076 | 1064 |
1077 for (size_t index = 0; index < arraysize(test_data); ++index) { | 1065 for (size_t index = 0; index < arraysize(test_data); ++index) { |
1078 const TestData& test = test_data[index]; | 1066 const TestData& test = test_data[index]; |
1079 SCOPED_TRACE(base::StringPrintf( | 1067 SCOPED_TRACE( |
1080 "index %zu, flavor %d", index, test.flavor)); | 1068 base::StringPrintf("index %zu, flavor %d", index, test.flavor)); |
1081 | 1069 |
1082 TestExcServerVariants test_exc_server_variants( | 1070 TestExcServerVariants test_exc_server_variants( |
1083 MACH_EXCEPTION_CODES | EXCEPTION_STATE_IDENTITY, | 1071 MACH_EXCEPTION_CODES | EXCEPTION_STATE_IDENTITY, |
1084 test.flavor, | 1072 test.flavor, |
1085 test.count); | 1073 test.count); |
1086 test_exc_server_variants.Run(); | 1074 test_exc_server_variants.Run(); |
1087 } | 1075 } |
1088 } | 1076 } |
1089 | 1077 |
| 1078 TEST(ExcServerVariants, ExcServerSuccessfulReturnValue) { |
| 1079 struct TestData { |
| 1080 exception_behavior_t behavior; |
| 1081 bool set_thread_state; |
| 1082 kern_return_t kr; |
| 1083 }; |
| 1084 const TestData kTestData[] = { |
| 1085 {EXCEPTION_DEFAULT, false, KERN_SUCCESS}, |
| 1086 {EXCEPTION_STATE, false, MACH_RCV_PORT_DIED}, |
| 1087 {EXCEPTION_STATE_IDENTITY, false, MACH_RCV_PORT_DIED}, |
| 1088 {kMachExceptionCodes | EXCEPTION_DEFAULT, false, KERN_SUCCESS}, |
| 1089 {kMachExceptionCodes | EXCEPTION_STATE, false, MACH_RCV_PORT_DIED}, |
| 1090 {kMachExceptionCodes | EXCEPTION_STATE_IDENTITY, |
| 1091 false, |
| 1092 MACH_RCV_PORT_DIED}, |
| 1093 {EXCEPTION_DEFAULT, true, KERN_SUCCESS}, |
| 1094 {EXCEPTION_STATE, true, KERN_SUCCESS}, |
| 1095 {EXCEPTION_STATE_IDENTITY, true, KERN_SUCCESS}, |
| 1096 {kMachExceptionCodes | EXCEPTION_DEFAULT, true, KERN_SUCCESS}, |
| 1097 {kMachExceptionCodes | EXCEPTION_STATE, true, KERN_SUCCESS}, |
| 1098 {kMachExceptionCodes | EXCEPTION_STATE_IDENTITY, true, KERN_SUCCESS}, |
| 1099 }; |
| 1100 |
| 1101 for (size_t index = 0; index < arraysize(kTestData); ++index) { |
| 1102 const TestData& test_data = kTestData[index]; |
| 1103 SCOPED_TRACE( |
| 1104 base::StringPrintf("index %zu, behavior %d, set_thread_state %s", |
| 1105 index, |
| 1106 test_data.behavior, |
| 1107 test_data.set_thread_state ? "true" : "false")); |
| 1108 |
| 1109 EXPECT_EQ(test_data.kr, |
| 1110 ExcServerSuccessfulReturnValue(test_data.behavior, |
| 1111 test_data.set_thread_state)); |
| 1112 } |
| 1113 } |
| 1114 |
1090 } // namespace | 1115 } // namespace |
OLD | NEW |