| 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 537 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 548 EXPECT_LE(sizeof(request), server.MachMessageServerRequestSize()); | 548 EXPECT_LE(sizeof(request), server.MachMessageServerRequestSize()); |
| 549 request.InitializeForTesting(); | 549 request.InitializeForTesting(); |
| 550 | 550 |
| 551 ExceptionRaiseReply reply; | 551 ExceptionRaiseReply reply; |
| 552 EXPECT_LE(sizeof(reply), server.MachMessageServerReplySize()); | 552 EXPECT_LE(sizeof(reply), server.MachMessageServerReplySize()); |
| 553 reply.InitializeForTesting(); | 553 reply.InitializeForTesting(); |
| 554 | 554 |
| 555 const exception_behavior_t kExceptionBehavior = EXCEPTION_DEFAULT; | 555 const exception_behavior_t kExceptionBehavior = EXCEPTION_DEFAULT; |
| 556 | 556 |
| 557 EXPECT_CALL(server, | 557 EXPECT_CALL(server, |
| 558 MockCatchMachException( | 558 MockCatchMachException(kExceptionBehavior, |
| 559 kExceptionBehavior, | 559 kServerLocalPort, |
| 560 kServerLocalPort, | 560 kExceptionThreadPort, |
| 561 kExceptionThreadPort, | 561 kExceptionTaskPort, |
| 562 kExceptionTaskPort, | 562 kExceptionType, |
| 563 kExceptionType, | 563 AreExceptionCodes(kTestExceptonCodes[0], |
| 564 AreExceptionCodes( | 564 kTestExceptonCodes[1]), |
| 565 kTestExceptonCodes[0], kTestExceptonCodes[1]), | 565 Pointee(Eq(THREAD_STATE_NONE)), |
| 566 Pointee(Eq(THREAD_STATE_NONE)), | 566 IsThreadStateCount(0u), |
| 567 IsThreadStateCount(0u), | 567 IsThreadStateCount(0u))) |
| 568 IsThreadStateCount(0u))) | |
| 569 .WillOnce(Return(KERN_SUCCESS)) | 568 .WillOnce(Return(KERN_SUCCESS)) |
| 570 .RetiresOnSaturation(); | 569 .RetiresOnSaturation(); |
| 571 | 570 |
| 572 bool destroy_complex_request = false; | 571 bool destroy_complex_request = false; |
| 573 EXPECT_TRUE(server.MachMessageServerFunction( | 572 EXPECT_TRUE(server.MachMessageServerFunction( |
| 574 reinterpret_cast<mach_msg_header_t*>(&request), | 573 reinterpret_cast<mach_msg_header_t*>(&request), |
| 575 reinterpret_cast<mach_msg_header_t*>(&reply), | 574 reinterpret_cast<mach_msg_header_t*>(&reply), |
| 576 &destroy_complex_request)); | 575 &destroy_complex_request)); |
| 577 EXPECT_TRUE(destroy_complex_request); | 576 EXPECT_TRUE(destroy_complex_request); |
| 578 | 577 |
| 579 reply.Verify(kExceptionBehavior); | 578 reply.Verify(kExceptionBehavior); |
| 580 } | 579 } |
| 581 | 580 |
| 582 TEST(ExcServerVariants, MockExceptionRaiseState) { | 581 TEST(ExcServerVariants, MockExceptionRaiseState) { |
| 583 ScopedDefaultValue<kern_return_t> default_kern_return_t(KERN_FAILURE); | 582 ScopedDefaultValue<kern_return_t> default_kern_return_t(KERN_FAILURE); |
| 584 | 583 |
| 585 MockUniversalMachExcServer server; | 584 MockUniversalMachExcServer server; |
| 586 | 585 |
| 587 ExceptionRaiseStateRequest request; | 586 ExceptionRaiseStateRequest request; |
| 588 EXPECT_LE(sizeof(request), server.MachMessageServerRequestSize()); | 587 EXPECT_LE(sizeof(request), server.MachMessageServerRequestSize()); |
| 589 request.InitializeForTesting(); | 588 request.InitializeForTesting(); |
| 590 | 589 |
| 591 ExceptionRaiseStateReply reply; | 590 ExceptionRaiseStateReply reply; |
| 592 EXPECT_LE(sizeof(reply), server.MachMessageServerReplySize()); | 591 EXPECT_LE(sizeof(reply), server.MachMessageServerReplySize()); |
| 593 reply.InitializeForTesting(); | 592 reply.InitializeForTesting(); |
| 594 | 593 |
| 595 const exception_behavior_t kExceptionBehavior = EXCEPTION_STATE; | 594 const exception_behavior_t kExceptionBehavior = EXCEPTION_STATE; |
| 596 | 595 |
| 597 EXPECT_CALL(server, | 596 EXPECT_CALL( |
| 598 MockCatchMachException( | 597 server, |
| 599 kExceptionBehavior, | 598 MockCatchMachException( |
| 600 kServerLocalPort, | 599 kExceptionBehavior, |
| 601 MACH_PORT_NULL, | 600 kServerLocalPort, |
| 602 MACH_PORT_NULL, | 601 MACH_PORT_NULL, |
| 603 kExceptionType, | 602 MACH_PORT_NULL, |
| 604 AreExceptionCodes( | 603 kExceptionType, |
| 605 kTestExceptonCodes[0], kTestExceptonCodes[1]), | 604 AreExceptionCodes(kTestExceptonCodes[0], kTestExceptonCodes[1]), |
| 606 Pointee(Eq(kThreadStateFlavor)), | 605 Pointee(Eq(kThreadStateFlavor)), |
| 607 IsThreadStateCount(kThreadStateFlavorCount), | 606 IsThreadStateCount(kThreadStateFlavorCount), |
| 608 IsThreadStateCount(arraysize(reply.new_state)))) | 607 IsThreadStateCount(arraysize(reply.new_state)))) |
| 609 .WillOnce(Return(KERN_SUCCESS)) | 608 .WillOnce(Return(KERN_SUCCESS)) |
| 610 .RetiresOnSaturation(); | 609 .RetiresOnSaturation(); |
| 611 | 610 |
| 612 bool destroy_complex_request = false; | 611 bool destroy_complex_request = false; |
| 613 EXPECT_TRUE(server.MachMessageServerFunction( | 612 EXPECT_TRUE(server.MachMessageServerFunction( |
| 614 reinterpret_cast<mach_msg_header_t*>(&request), | 613 reinterpret_cast<mach_msg_header_t*>(&request), |
| 615 reinterpret_cast<mach_msg_header_t*>(&reply), | 614 reinterpret_cast<mach_msg_header_t*>(&reply), |
| 616 &destroy_complex_request)); | 615 &destroy_complex_request)); |
| 617 | 616 |
| 618 // The request wasn’t complex, so nothing got a chance to change the value of | 617 // The request wasn’t complex, so nothing got a chance to change the value of |
| (...skipping 11 matching lines...) Expand all Loading... |
| 630 ExceptionRaiseStateIdentityRequest request; | 629 ExceptionRaiseStateIdentityRequest request; |
| 631 EXPECT_LE(sizeof(request), server.MachMessageServerRequestSize()); | 630 EXPECT_LE(sizeof(request), server.MachMessageServerRequestSize()); |
| 632 request.InitializeForTesting(); | 631 request.InitializeForTesting(); |
| 633 | 632 |
| 634 ExceptionRaiseStateIdentityReply reply; | 633 ExceptionRaiseStateIdentityReply reply; |
| 635 EXPECT_LE(sizeof(reply), server.MachMessageServerReplySize()); | 634 EXPECT_LE(sizeof(reply), server.MachMessageServerReplySize()); |
| 636 reply.InitializeForTesting(); | 635 reply.InitializeForTesting(); |
| 637 | 636 |
| 638 const exception_behavior_t kExceptionBehavior = EXCEPTION_STATE_IDENTITY; | 637 const exception_behavior_t kExceptionBehavior = EXCEPTION_STATE_IDENTITY; |
| 639 | 638 |
| 640 EXPECT_CALL(server, | 639 EXPECT_CALL( |
| 641 MockCatchMachException( | 640 server, |
| 642 kExceptionBehavior, | 641 MockCatchMachException( |
| 643 kServerLocalPort, | 642 kExceptionBehavior, |
| 644 kExceptionThreadPort, | 643 kServerLocalPort, |
| 645 kExceptionTaskPort, | 644 kExceptionThreadPort, |
| 646 kExceptionType, | 645 kExceptionTaskPort, |
| 647 AreExceptionCodes( | 646 kExceptionType, |
| 648 kTestExceptonCodes[0], kTestExceptonCodes[1]), | 647 AreExceptionCodes(kTestExceptonCodes[0], kTestExceptonCodes[1]), |
| 649 Pointee(Eq(kThreadStateFlavor)), | 648 Pointee(Eq(kThreadStateFlavor)), |
| 650 IsThreadStateCount(kThreadStateFlavorCount), | 649 IsThreadStateCount(kThreadStateFlavorCount), |
| 651 IsThreadStateCount(arraysize(reply.new_state)))) | 650 IsThreadStateCount(arraysize(reply.new_state)))) |
| 652 .WillOnce(Return(KERN_SUCCESS)) | 651 .WillOnce(Return(KERN_SUCCESS)) |
| 653 .RetiresOnSaturation(); | 652 .RetiresOnSaturation(); |
| 654 | 653 |
| 655 bool destroy_complex_request = false; | 654 bool destroy_complex_request = false; |
| 656 EXPECT_TRUE(server.MachMessageServerFunction( | 655 EXPECT_TRUE(server.MachMessageServerFunction( |
| 657 reinterpret_cast<mach_msg_header_t*>(&request), | 656 reinterpret_cast<mach_msg_header_t*>(&request), |
| 658 reinterpret_cast<mach_msg_header_t*>(&reply), | 657 reinterpret_cast<mach_msg_header_t*>(&reply), |
| 659 &destroy_complex_request)); | 658 &destroy_complex_request)); |
| 660 EXPECT_TRUE(destroy_complex_request); | 659 EXPECT_TRUE(destroy_complex_request); |
| 661 | 660 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 673 | 672 |
| 674 MachExceptionRaiseReply reply; | 673 MachExceptionRaiseReply reply; |
| 675 EXPECT_LE(sizeof(reply), server.MachMessageServerReplySize()); | 674 EXPECT_LE(sizeof(reply), server.MachMessageServerReplySize()); |
| 676 reply.InitializeForTesting(); | 675 reply.InitializeForTesting(); |
| 677 | 676 |
| 678 const exception_behavior_t kExceptionBehavior = | 677 const exception_behavior_t kExceptionBehavior = |
| 679 EXCEPTION_DEFAULT | MACH_EXCEPTION_CODES; | 678 EXCEPTION_DEFAULT | MACH_EXCEPTION_CODES; |
| 680 | 679 |
| 681 EXPECT_CALL( | 680 EXPECT_CALL( |
| 682 server, | 681 server, |
| 683 MockCatchMachException( | 682 MockCatchMachException(kExceptionBehavior, |
| 684 kExceptionBehavior, | 683 kServerLocalPort, |
| 685 kServerLocalPort, | 684 kExceptionThreadPort, |
| 686 kExceptionThreadPort, | 685 kExceptionTaskPort, |
| 687 kExceptionTaskPort, | 686 kExceptionType, |
| 688 kExceptionType, | 687 AreExceptionCodes(kTestMachExceptionCodes[0], |
| 689 AreExceptionCodes( | 688 kTestMachExceptionCodes[1]), |
| 690 kTestMachExceptionCodes[0], kTestMachExceptionCodes[1]), | 689 Pointee(Eq(THREAD_STATE_NONE)), |
| 691 Pointee(Eq(THREAD_STATE_NONE)), | 690 IsThreadStateCount(0u), |
| 692 IsThreadStateCount(0u), | 691 IsThreadStateCount(0u))) |
| 693 IsThreadStateCount(0u))) | |
| 694 .WillOnce(Return(KERN_SUCCESS)) | 692 .WillOnce(Return(KERN_SUCCESS)) |
| 695 .RetiresOnSaturation(); | 693 .RetiresOnSaturation(); |
| 696 | 694 |
| 697 bool destroy_complex_request = false; | 695 bool destroy_complex_request = false; |
| 698 EXPECT_TRUE(server.MachMessageServerFunction( | 696 EXPECT_TRUE(server.MachMessageServerFunction( |
| 699 reinterpret_cast<mach_msg_header_t*>(&request), | 697 reinterpret_cast<mach_msg_header_t*>(&request), |
| 700 reinterpret_cast<mach_msg_header_t*>(&reply), | 698 reinterpret_cast<mach_msg_header_t*>(&reply), |
| 701 &destroy_complex_request)); | 699 &destroy_complex_request)); |
| 702 EXPECT_TRUE(destroy_complex_request); | 700 EXPECT_TRUE(destroy_complex_request); |
| 703 | 701 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 715 | 713 |
| 716 MachExceptionRaiseStateReply reply; | 714 MachExceptionRaiseStateReply reply; |
| 717 EXPECT_LE(sizeof(reply), server.MachMessageServerReplySize()); | 715 EXPECT_LE(sizeof(reply), server.MachMessageServerReplySize()); |
| 718 reply.InitializeForTesting(); | 716 reply.InitializeForTesting(); |
| 719 | 717 |
| 720 const exception_behavior_t kExceptionBehavior = | 718 const exception_behavior_t kExceptionBehavior = |
| 721 EXCEPTION_STATE | MACH_EXCEPTION_CODES; | 719 EXCEPTION_STATE | MACH_EXCEPTION_CODES; |
| 722 | 720 |
| 723 EXPECT_CALL( | 721 EXPECT_CALL( |
| 724 server, | 722 server, |
| 725 MockCatchMachException( | 723 MockCatchMachException(kExceptionBehavior, |
| 726 kExceptionBehavior, | 724 kServerLocalPort, |
| 727 kServerLocalPort, | 725 MACH_PORT_NULL, |
| 728 MACH_PORT_NULL, | 726 MACH_PORT_NULL, |
| 729 MACH_PORT_NULL, | 727 kExceptionType, |
| 730 kExceptionType, | 728 AreExceptionCodes(kTestMachExceptionCodes[0], |
| 731 AreExceptionCodes( | 729 kTestMachExceptionCodes[1]), |
| 732 kTestMachExceptionCodes[0], kTestMachExceptionCodes[1]), | 730 Pointee(Eq(kThreadStateFlavor)), |
| 733 Pointee(Eq(kThreadStateFlavor)), | 731 IsThreadStateCount(kThreadStateFlavorCount), |
| 734 IsThreadStateCount(kThreadStateFlavorCount), | 732 IsThreadStateCount(arraysize(reply.new_state)))) |
| 735 IsThreadStateCount(arraysize(reply.new_state)))) | |
| 736 .WillOnce(Return(KERN_SUCCESS)) | 733 .WillOnce(Return(KERN_SUCCESS)) |
| 737 .RetiresOnSaturation(); | 734 .RetiresOnSaturation(); |
| 738 | 735 |
| 739 bool destroy_complex_request = false; | 736 bool destroy_complex_request = false; |
| 740 EXPECT_TRUE(server.MachMessageServerFunction( | 737 EXPECT_TRUE(server.MachMessageServerFunction( |
| 741 reinterpret_cast<mach_msg_header_t*>(&request), | 738 reinterpret_cast<mach_msg_header_t*>(&request), |
| 742 reinterpret_cast<mach_msg_header_t*>(&reply), | 739 reinterpret_cast<mach_msg_header_t*>(&reply), |
| 743 &destroy_complex_request)); | 740 &destroy_complex_request)); |
| 744 | 741 |
| 745 // The request wasn’t complex, so nothing got a chance to change the value of | 742 // The request wasn’t complex, so nothing got a chance to change the value of |
| (...skipping 14 matching lines...) Expand all Loading... |
| 760 | 757 |
| 761 MachExceptionRaiseStateIdentityReply reply; | 758 MachExceptionRaiseStateIdentityReply reply; |
| 762 EXPECT_LE(sizeof(reply), server.MachMessageServerReplySize()); | 759 EXPECT_LE(sizeof(reply), server.MachMessageServerReplySize()); |
| 763 reply.InitializeForTesting(); | 760 reply.InitializeForTesting(); |
| 764 | 761 |
| 765 const exception_behavior_t kExceptionBehavior = | 762 const exception_behavior_t kExceptionBehavior = |
| 766 EXCEPTION_STATE_IDENTITY | MACH_EXCEPTION_CODES; | 763 EXCEPTION_STATE_IDENTITY | MACH_EXCEPTION_CODES; |
| 767 | 764 |
| 768 EXPECT_CALL( | 765 EXPECT_CALL( |
| 769 server, | 766 server, |
| 770 MockCatchMachException( | 767 MockCatchMachException(kExceptionBehavior, |
| 771 kExceptionBehavior, | 768 kServerLocalPort, |
| 772 kServerLocalPort, | 769 kExceptionThreadPort, |
| 773 kExceptionThreadPort, | 770 kExceptionTaskPort, |
| 774 kExceptionTaskPort, | 771 kExceptionType, |
| 775 kExceptionType, | 772 AreExceptionCodes(kTestMachExceptionCodes[0], |
| 776 AreExceptionCodes( | 773 kTestMachExceptionCodes[1]), |
| 777 kTestMachExceptionCodes[0], kTestMachExceptionCodes[1]), | 774 Pointee(Eq(kThreadStateFlavor)), |
| 778 Pointee(Eq(kThreadStateFlavor)), | 775 IsThreadStateCount(kThreadStateFlavorCount), |
| 779 IsThreadStateCount(kThreadStateFlavorCount), | 776 IsThreadStateCount(arraysize(reply.new_state)))) |
| 780 IsThreadStateCount(arraysize(reply.new_state)))) | |
| 781 .WillOnce(Return(KERN_SUCCESS)) | 777 .WillOnce(Return(KERN_SUCCESS)) |
| 782 .RetiresOnSaturation(); | 778 .RetiresOnSaturation(); |
| 783 | 779 |
| 784 bool destroy_complex_request = false; | 780 bool destroy_complex_request = false; |
| 785 EXPECT_TRUE(server.MachMessageServerFunction( | 781 EXPECT_TRUE(server.MachMessageServerFunction( |
| 786 reinterpret_cast<mach_msg_header_t*>(&request), | 782 reinterpret_cast<mach_msg_header_t*>(&request), |
| 787 reinterpret_cast<mach_msg_header_t*>(&reply), | 783 reinterpret_cast<mach_msg_header_t*>(&reply), |
| 788 &destroy_complex_request)); | 784 &destroy_complex_request)); |
| 789 EXPECT_TRUE(destroy_complex_request); | 785 EXPECT_TRUE(destroy_complex_request); |
| 790 | 786 |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 862 public MachMultiprocess { | 858 public MachMultiprocess { |
| 863 public: | 859 public: |
| 864 TestExcServerVariants(exception_behavior_t behavior, | 860 TestExcServerVariants(exception_behavior_t behavior, |
| 865 thread_state_flavor_t flavor, | 861 thread_state_flavor_t flavor, |
| 866 mach_msg_type_number_t state_count) | 862 mach_msg_type_number_t state_count) |
| 867 : UniversalMachExcServer(), | 863 : UniversalMachExcServer(), |
| 868 MachMultiprocess(), | 864 MachMultiprocess(), |
| 869 behavior_(behavior), | 865 behavior_(behavior), |
| 870 flavor_(flavor), | 866 flavor_(flavor), |
| 871 state_count_(state_count), | 867 state_count_(state_count), |
| 872 handled_(false) { | 868 handled_(false) {} |
| 873 } | |
| 874 | 869 |
| 875 // UniversalMachExcServer: | 870 // UniversalMachExcServer: |
| 876 | 871 |
| 877 virtual kern_return_t CatchMachException( | 872 virtual kern_return_t CatchMachException( |
| 878 exception_behavior_t behavior, | 873 exception_behavior_t behavior, |
| 879 exception_handler_t exception_port, | 874 exception_handler_t exception_port, |
| 880 thread_t thread, | 875 thread_t thread, |
| 881 task_t task, | 876 task_t task, |
| 882 exception_type_t exception, | 877 exception_type_t exception, |
| 883 const mach_exception_data_type_t* code, | 878 const mach_exception_data_type_t* code, |
| (...skipping 45 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 |