| 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 488 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 499 *result_listener << ", "; | 499 *result_listener << ", "; |
| 500 } | 500 } |
| 501 } | 501 } |
| 502 *result_listener << ")"; | 502 *result_listener << ")"; |
| 503 | 503 |
| 504 return false; | 504 return false; |
| 505 } | 505 } |
| 506 | 506 |
| 507 // Matcher for ThreadState and ConstThreadState, testing that *state_count is | 507 // Matcher for ThreadState and ConstThreadState, testing that *state_count is |
| 508 // present and matches the specified value. If 0 is specified for the count, | 508 // present and matches the specified value. If 0 is specified for the count, |
| 509 // state must be NULL (not present), otherwise state must be non-NULL (present). | 509 // |state| must be nullptr (not present), otherwise |state| must not be nullptr |
| 510 // (present). |
| 510 MATCHER_P(IsThreadStateCount, state_count, "") { | 511 MATCHER_P(IsThreadStateCount, state_count, "") { |
| 511 if (!arg) { | 512 if (!arg) { |
| 512 return false; | 513 return false; |
| 513 } | 514 } |
| 514 if (!arg->state_count) { | 515 if (!arg->state_count) { |
| 515 *result_listener << "state_count NULL"; | 516 *result_listener << "state_count nullptr"; |
| 516 return false; | 517 return false; |
| 517 } | 518 } |
| 518 if (*(arg->state_count) != state_count) { | 519 if (*(arg->state_count) != state_count) { |
| 519 *result_listener << "*state_count " << *(arg->state_count); | 520 *result_listener << "*state_count " << *(arg->state_count); |
| 520 return false; | 521 return false; |
| 521 } | 522 } |
| 522 if (state_count) { | 523 if (state_count) { |
| 523 if (!arg->state) { | 524 if (!arg->state) { |
| 524 *result_listener << "*state_count " << state_count << ", state NULL"; | 525 *result_listener << "*state_count " << state_count << ", state nullptr"; |
| 525 return false; | 526 return false; |
| 526 } | 527 } |
| 527 } else { | 528 } else { |
| 528 if (arg->state) { | 529 if (arg->state) { |
| 529 *result_listener << "*state_count 0, state non-NULL (" << arg->state | 530 *result_listener << "*state_count 0, state non-nullptr (" << arg->state |
| 530 << ")"; | 531 << ")"; |
| 531 return false; | 532 return false; |
| 532 } | 533 } |
| 533 } | 534 } |
| 534 return true; | 535 return true; |
| 535 } | 536 } |
| 536 | 537 |
| 537 template <typename T> | 538 template <typename T> |
| 538 class ScopedDefaultValue { | 539 class ScopedDefaultValue { |
| 539 public: | 540 public: |
| (...skipping 366 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 906 } | 907 } |
| 907 | 908 |
| 908 EXPECT_EQ(EXC_CRASH, exception); | 909 EXPECT_EQ(EXC_CRASH, exception); |
| 909 EXPECT_EQ(2u, code_count); | 910 EXPECT_EQ(2u, code_count); |
| 910 | 911 |
| 911 // The exception and code_count checks above would ideally use ASSERT_EQ so | 912 // The exception and code_count checks above would ideally use ASSERT_EQ so |
| 912 // that the next conditional would not be necessary, but ASSERT_* requires a | 913 // that the next conditional would not be necessary, but ASSERT_* requires a |
| 913 // function returning type void, and the interface dictates otherwise here. | 914 // function returning type void, and the interface dictates otherwise here. |
| 914 if (exception == EXC_CRASH && code_count >= 1) { | 915 if (exception == EXC_CRASH && code_count >= 1) { |
| 915 int signal; | 916 int signal; |
| 916 ExcCrashRecoverOriginalException(code[0], NULL, &signal); | 917 ExcCrashRecoverOriginalException(code[0], nullptr, &signal); |
| 917 SetExpectedChildTermination(kTerminationSignal, signal); | 918 SetExpectedChildTermination(kTerminationSignal, signal); |
| 918 } | 919 } |
| 919 | 920 |
| 920 const bool has_state = ExceptionBehaviorHasState(behavior); | 921 const bool has_state = ExceptionBehaviorHasState(behavior); |
| 921 if (has_state) { | 922 if (has_state) { |
| 922 EXPECT_EQ(flavor_, *flavor); | 923 EXPECT_EQ(flavor_, *flavor); |
| 923 EXPECT_EQ(state_count_, old_state_count); | 924 EXPECT_EQ(state_count_, old_state_count); |
| 924 EXPECT_NE(static_cast<const natural_t*>(NULL), old_state); | 925 EXPECT_NE(nullptr, old_state); |
| 925 EXPECT_EQ(static_cast<mach_msg_type_number_t>(THREAD_STATE_MAX), | 926 EXPECT_EQ(static_cast<mach_msg_type_number_t>(THREAD_STATE_MAX), |
| 926 *new_state_count); | 927 *new_state_count); |
| 927 EXPECT_NE(static_cast<natural_t*>(NULL), new_state); | 928 EXPECT_NE(nullptr, new_state); |
| 928 } else { | 929 } else { |
| 929 EXPECT_EQ(THREAD_STATE_NONE, *flavor); | 930 EXPECT_EQ(THREAD_STATE_NONE, *flavor); |
| 930 EXPECT_EQ(0u, old_state_count); | 931 EXPECT_EQ(0u, old_state_count); |
| 931 EXPECT_EQ(NULL, old_state); | 932 EXPECT_EQ(nullptr, old_state); |
| 932 EXPECT_EQ(0u, *new_state_count); | 933 EXPECT_EQ(0u, *new_state_count); |
| 933 EXPECT_EQ(NULL, new_state); | 934 EXPECT_EQ(nullptr, new_state); |
| 934 } | 935 } |
| 935 | 936 |
| 936 return ExcServerSuccessfulReturnValue(behavior, false); | 937 return ExcServerSuccessfulReturnValue(behavior, false); |
| 937 } | 938 } |
| 938 | 939 |
| 939 private: | 940 private: |
| 940 // MachMultiprocess: | 941 // MachMultiprocess: |
| 941 | 942 |
| 942 virtual void MachMultiprocessParent() override { | 943 virtual void MachMultiprocessParent() override { |
| 943 kern_return_t kr = MachMessageServer::Run(this, | 944 kern_return_t kr = MachMessageServer::Run(this, |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1015 TEST(ExcServerVariants, ThreadStates) { | 1016 TEST(ExcServerVariants, ThreadStates) { |
| 1016 // So far, all of the tests worked with MACHINE_THREAD_STATE. Now try all of | 1017 // So far, all of the tests worked with MACHINE_THREAD_STATE. Now try all of |
| 1017 // the other thread state flavors that are expected to work. | 1018 // the other thread state flavors that are expected to work. |
| 1018 | 1019 |
| 1019 struct TestData { | 1020 struct TestData { |
| 1020 thread_state_flavor_t flavor; | 1021 thread_state_flavor_t flavor; |
| 1021 mach_msg_type_number_t count; | 1022 mach_msg_type_number_t count; |
| 1022 }; | 1023 }; |
| 1023 const TestData test_data[] = { | 1024 const TestData test_data[] = { |
| 1024 #if defined(ARCH_CPU_X86_FAMILY) | 1025 #if defined(ARCH_CPU_X86_FAMILY) |
| 1025 // For the x86 family, exception handlers can only properly receive the | 1026 // For the x86 family, exception handlers can only properly receive the |
| 1026 // thread, float, and exception state flavors. There’s a bug in the kernel | 1027 // thread, float, and exception state flavors. There’s a bug in the kernel |
| 1027 // that causes it to call thread_getstatus() (a wrapper for the more | 1028 // that causes it to call thread_getstatus() (a wrapper for the more |
| 1028 // familiar thread_get_state()) with an incorrect state buffer size | 1029 // familiar thread_get_state()) with an incorrect state buffer size |
| 1029 // parameter when delivering an exception. 10.9.4 | 1030 // parameter when delivering an exception. 10.9.4 |
| 1030 // xnu-2422.110.17/osfmk/kern/exception.c exception_deliver() uses the | 1031 // xnu-2422.110.17/osfmk/kern/exception.c exception_deliver() uses the |
| 1031 // _MachineStateCount[] array indexed by the flavor number to obtain the | 1032 // _MachineStateCount[] array indexed by the flavor number to obtain the |
| 1032 // buffer size. 10.9.4 xnu-2422.110.17/osfmk/i386/pcb.c contains the | 1033 // buffer size. 10.9.4 xnu-2422.110.17/osfmk/i386/pcb.c contains the |
| 1033 // definition of this array for the x86 family. The slots corresponding to | 1034 // definition of this array for the x86 family. The slots corresponding to |
| 1034 // thread, float, and exception state flavors in both native-width (32- and | 1035 // thread, float, and exception state flavors in both native-width (32- |
| 1035 // 64-bit) and universal are correct, but the remaining elements in the | 1036 // and 64-bit) and universal are correct, but the remaining elements in |
| 1036 // array are not. This includes elements that would correspond to debug and | 1037 // the array are not. This includes elements that would correspond to |
| 1037 // AVX state flavors, so these cannot be tested here. | 1038 // debug and AVX state flavors, so these cannot be tested here. |
| 1038 // | 1039 // |
| 1039 // When machine_thread_get_state() (the machine-specific implementation of | 1040 // When machine_thread_get_state() (the machine-specific implementation of |
| 1040 // thread_get_state()) encounters an undersized buffer as reported by the | 1041 // thread_get_state()) encounters an undersized buffer as reported by the |
| 1041 // buffer size parameter, it returns KERN_INVALID_ARGUMENT, which causes | 1042 // buffer size parameter, it returns KERN_INVALID_ARGUMENT, which causes |
| 1042 // exception_deliver() to not actually deliver the exception and instead | 1043 // exception_deliver() to not actually deliver the exception and instead |
| 1043 // return that error code to exception_triage() as well. | 1044 // return that error code to exception_triage() as well. |
| 1044 // | 1045 // |
| 1045 // This bug is filed as radar 18312067. | 1046 // This bug is filed as radar 18312067. |
| 1046 // | 1047 // |
| 1047 // Additionaly, the AVX state flavors are also not tested because they’re | 1048 // Additionaly, the AVX state flavors are also not tested because they’re |
| 1048 // not available on all CPUs and OS versions. | 1049 // not available on all CPUs and OS versions. |
| 1049 #if defined(ARCH_CPU_X86) | 1050 #if defined(ARCH_CPU_X86) |
| 1050 {x86_THREAD_STATE32, x86_THREAD_STATE32_COUNT}, | 1051 {x86_THREAD_STATE32, x86_THREAD_STATE32_COUNT}, |
| 1051 {x86_FLOAT_STATE32, x86_FLOAT_STATE32_COUNT}, | 1052 {x86_FLOAT_STATE32, x86_FLOAT_STATE32_COUNT}, |
| 1052 {x86_EXCEPTION_STATE32, x86_EXCEPTION_STATE32_COUNT}, | 1053 {x86_EXCEPTION_STATE32, x86_EXCEPTION_STATE32_COUNT}, |
| 1053 #endif | 1054 #endif |
| 1054 #if defined(ARCH_CPU_X86_64) | 1055 #if defined(ARCH_CPU_X86_64) |
| 1055 {x86_THREAD_STATE64, x86_THREAD_STATE64_COUNT}, | 1056 {x86_THREAD_STATE64, x86_THREAD_STATE64_COUNT}, |
| 1056 {x86_FLOAT_STATE64, x86_FLOAT_STATE64_COUNT}, | 1057 {x86_FLOAT_STATE64, x86_FLOAT_STATE64_COUNT}, |
| 1057 {x86_EXCEPTION_STATE64, x86_EXCEPTION_STATE64_COUNT}, | 1058 {x86_EXCEPTION_STATE64, x86_EXCEPTION_STATE64_COUNT}, |
| 1058 #endif | 1059 #endif |
| 1059 {x86_THREAD_STATE, x86_THREAD_STATE_COUNT}, | 1060 {x86_THREAD_STATE, x86_THREAD_STATE_COUNT}, |
| 1060 {x86_FLOAT_STATE, x86_FLOAT_STATE_COUNT}, | 1061 {x86_FLOAT_STATE, x86_FLOAT_STATE_COUNT}, |
| 1061 {x86_EXCEPTION_STATE, x86_EXCEPTION_STATE_COUNT}, | 1062 {x86_EXCEPTION_STATE, x86_EXCEPTION_STATE_COUNT}, |
| 1062 #else | 1063 #else |
| 1063 #error Port this test to your CPU architecture. | 1064 #error Port this test to your CPU architecture. |
| 1064 #endif | 1065 #endif |
| 1065 }; | 1066 }; |
| 1066 | 1067 |
| 1067 for (size_t index = 0; index < arraysize(test_data); ++index) { | 1068 for (size_t index = 0; index < arraysize(test_data); ++index) { |
| 1068 const TestData& test = test_data[index]; | 1069 const TestData& test = test_data[index]; |
| 1069 SCOPED_TRACE( | 1070 SCOPED_TRACE( |
| 1070 base::StringPrintf("index %zu, flavor %d", index, test.flavor)); | 1071 base::StringPrintf("index %zu, flavor %d", index, test.flavor)); |
| 1071 | 1072 |
| 1072 TestExcServerVariants test_exc_server_variants( | 1073 TestExcServerVariants test_exc_server_variants( |
| 1073 MACH_EXCEPTION_CODES | EXCEPTION_STATE_IDENTITY, | 1074 MACH_EXCEPTION_CODES | EXCEPTION_STATE_IDENTITY, |
| 1074 test.flavor, | 1075 test.flavor, |
| 1075 test.count); | 1076 test.count); |
| 1076 test_exc_server_variants.Run(); | 1077 test_exc_server_variants.Run(); |
| 1077 } | 1078 } |
| 1078 } | 1079 } |
| 1079 | 1080 |
| 1080 TEST(ExcServerVariants, ExcCrashRecoverOriginalException) { | 1081 TEST(ExcServerVariants, ExcCrashRecoverOriginalException) { |
| 1081 struct TestData { | 1082 struct TestData { |
| 1082 mach_exception_code_t code_0; | 1083 mach_exception_code_t code_0; |
| 1083 exception_type_t exception; | 1084 exception_type_t exception; |
| 1084 mach_exception_code_t original_code_0; | 1085 mach_exception_code_t original_code_0; |
| 1085 int signal; | 1086 int signal; |
| 1086 }; | 1087 }; |
| 1087 const TestData kTestData[] = { | 1088 const TestData kTestData[] = { |
| 1088 {0xb100001, EXC_BAD_ACCESS, KERN_INVALID_ADDRESS, SIGSEGV}, | 1089 {0xb100001, EXC_BAD_ACCESS, KERN_INVALID_ADDRESS, SIGSEGV}, |
| 1089 {0xb100002, EXC_BAD_ACCESS, KERN_PROTECTION_FAILURE, SIGSEGV}, | 1090 {0xb100002, EXC_BAD_ACCESS, KERN_PROTECTION_FAILURE, SIGSEGV}, |
| 1090 {0xa100002, EXC_BAD_ACCESS, KERN_PROTECTION_FAILURE, SIGBUS}, | 1091 {0xa100002, EXC_BAD_ACCESS, KERN_PROTECTION_FAILURE, SIGBUS}, |
| 1091 {0x4200001, EXC_BAD_INSTRUCTION, 1, SIGILL}, | 1092 {0x4200001, EXC_BAD_INSTRUCTION, 1, SIGILL}, |
| 1092 {0x8300001, EXC_ARITHMETIC, 1, SIGFPE}, | 1093 {0x8300001, EXC_ARITHMETIC, 1, SIGFPE}, |
| 1093 {0x5600002, EXC_BREAKPOINT, 2, SIGTRAP}, | 1094 {0x5600002, EXC_BREAKPOINT, 2, SIGTRAP}, |
| 1094 {0x3000000, 0, 0, SIGQUIT}, | 1095 {0x3000000, 0, 0, SIGQUIT}, |
| 1095 {0x6000000, 0, 0, SIGABRT}, | 1096 {0x6000000, 0, 0, SIGABRT}, |
| 1096 {0xc000000, 0, 0, SIGSYS}, | 1097 {0xc000000, 0, 0, SIGSYS}, |
| 1097 {0, 0, 0, 0}, | 1098 {0, 0, 0, 0}, |
| 1098 }; | 1099 }; |
| 1099 | 1100 |
| 1100 for (size_t index = 0; index < arraysize(kTestData); ++index) { | 1101 for (size_t index = 0; index < arraysize(kTestData); ++index) { |
| 1101 const TestData& test_data = kTestData[index]; | 1102 const TestData& test_data = kTestData[index]; |
| 1102 SCOPED_TRACE(base::StringPrintf("index %zu, code_0 0x%llx", | 1103 SCOPED_TRACE(base::StringPrintf( |
| 1103 index, | 1104 "index %zu, code_0 0x%llx", index, test_data.code_0)); |
| 1104 test_data.code_0)); | |
| 1105 | 1105 |
| 1106 mach_exception_code_t original_code_0; | 1106 mach_exception_code_t original_code_0; |
| 1107 int signal; | 1107 int signal; |
| 1108 exception_type_t exception = | 1108 exception_type_t exception = ExcCrashRecoverOriginalException( |
| 1109 ExcCrashRecoverOriginalException(test_data.code_0, | 1109 test_data.code_0, &original_code_0, &signal); |
| 1110 &original_code_0, | |
| 1111 &signal); | |
| 1112 | 1110 |
| 1113 EXPECT_EQ(test_data.exception, exception); | 1111 EXPECT_EQ(test_data.exception, exception); |
| 1114 EXPECT_EQ(test_data.original_code_0, original_code_0); | 1112 EXPECT_EQ(test_data.original_code_0, original_code_0); |
| 1115 EXPECT_EQ(test_data.signal, signal); | 1113 EXPECT_EQ(test_data.signal, signal); |
| 1116 } | 1114 } |
| 1117 | 1115 |
| 1118 // Now make sure that ExcCrashRecoverOriginalException() properly ignores | 1116 // Now make sure that ExcCrashRecoverOriginalException() properly ignores |
| 1119 // optional arguments. | 1117 // optional arguments. |
| 1120 static_assert(arraysize(kTestData) >= 1, "must have something to test"); | 1118 static_assert(arraysize(kTestData) >= 1, "must have something to test"); |
| 1121 const TestData& test_data = kTestData[0]; | 1119 const TestData& test_data = kTestData[0]; |
| 1122 EXPECT_EQ(test_data.exception, | 1120 EXPECT_EQ( |
| 1123 ExcCrashRecoverOriginalException(test_data.code_0, NULL, NULL)); | 1121 test_data.exception, |
| 1122 ExcCrashRecoverOriginalException(test_data.code_0, nullptr, nullptr)); |
| 1124 | 1123 |
| 1125 mach_exception_code_t original_code_0; | 1124 mach_exception_code_t original_code_0; |
| 1126 EXPECT_EQ(test_data.exception, | 1125 EXPECT_EQ(test_data.exception, |
| 1127 ExcCrashRecoverOriginalException( | 1126 ExcCrashRecoverOriginalException( |
| 1128 test_data.code_0, &original_code_0, NULL)); | 1127 test_data.code_0, &original_code_0, nullptr)); |
| 1129 EXPECT_EQ(test_data.original_code_0, original_code_0); | 1128 EXPECT_EQ(test_data.original_code_0, original_code_0); |
| 1130 | 1129 |
| 1131 int signal; | 1130 int signal; |
| 1132 EXPECT_EQ(test_data.exception, | 1131 EXPECT_EQ( |
| 1133 ExcCrashRecoverOriginalException(test_data.code_0, NULL, &signal)); | 1132 test_data.exception, |
| 1133 ExcCrashRecoverOriginalException(test_data.code_0, nullptr, &signal)); |
| 1134 EXPECT_EQ(test_data.signal, signal); | 1134 EXPECT_EQ(test_data.signal, signal); |
| 1135 } | 1135 } |
| 1136 | 1136 |
| 1137 TEST(ExcServerVariants, ExcServerSuccessfulReturnValue) { | 1137 TEST(ExcServerVariants, ExcServerSuccessfulReturnValue) { |
| 1138 struct TestData { | 1138 struct TestData { |
| 1139 exception_behavior_t behavior; | 1139 exception_behavior_t behavior; |
| 1140 bool set_thread_state; | 1140 bool set_thread_state; |
| 1141 kern_return_t kr; | 1141 kern_return_t kr; |
| 1142 }; | 1142 }; |
| 1143 const TestData kTestData[] = { | 1143 const TestData kTestData[] = { |
| (...skipping 23 matching lines...) Expand all Loading... |
| 1167 | 1167 |
| 1168 EXPECT_EQ(test_data.kr, | 1168 EXPECT_EQ(test_data.kr, |
| 1169 ExcServerSuccessfulReturnValue(test_data.behavior, | 1169 ExcServerSuccessfulReturnValue(test_data.behavior, |
| 1170 test_data.set_thread_state)); | 1170 test_data.set_thread_state)); |
| 1171 } | 1171 } |
| 1172 } | 1172 } |
| 1173 | 1173 |
| 1174 } // namespace | 1174 } // namespace |
| 1175 } // namespace test | 1175 } // namespace test |
| 1176 } // namespace crashpad | 1176 } // namespace crashpad |
| OLD | NEW |