| 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, |
| 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 12 // See the License for the specific language governing permissions and | 12 // See the License for the specific language governing permissions and |
| 13 // limitations under the License. | 13 // limitations under the License. |
| 14 | 14 |
| 15 #include "util/mach/exc_server_variants.h" | 15 #include "util/mach/exc_server_variants.h" |
| 16 | 16 |
| 17 #include <mach/mach.h> | 17 #include <mach/mach.h> |
| 18 #include <signal.h> | 18 #include <signal.h> |
| 19 #include <string.h> | 19 #include <string.h> |
| 20 | 20 |
| 21 #include "base/strings/stringprintf.h" | 21 #include "base/strings/stringprintf.h" |
| 22 #include "gmock/gmock.h" | 22 #include "gmock/gmock.h" |
| 23 #include "gtest/gtest.h" | 23 #include "gtest/gtest.h" |
| 24 #include "util/mach/exception_behaviors.h" | 24 #include "util/mach/exception_behaviors.h" |
| 25 #include "util/mach/mach_extensions.h" | 25 #include "util/mach/mach_extensions.h" |
| 26 #include "util/mach/mach_message_util.h" |
| 26 #include "util/test/mac/mach_errors.h" | 27 #include "util/test/mac/mach_errors.h" |
| 27 #include "util/test/mac/mach_multiprocess.h" | 28 #include "util/test/mac/mach_multiprocess.h" |
| 28 | 29 |
| 29 namespace crashpad { | 30 namespace crashpad { |
| 30 namespace test { | 31 namespace test { |
| 31 namespace { | 32 namespace { |
| 32 | 33 |
| 33 using testing::DefaultValue; | 34 using testing::DefaultValue; |
| 34 using testing::Eq; | 35 using testing::Eq; |
| 35 using testing::Pointee; | 36 using testing::Pointee; |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 75 // of the structures from both exc.h and mach_exc.h here in this file, and | 76 // of the structures from both exc.h and mach_exc.h here in this file, and |
| 76 // provide the initialization and verification code as methods in true | 77 // provide the initialization and verification code as methods in true |
| 77 // object-oriented fashion. | 78 // object-oriented fashion. |
| 78 | 79 |
| 79 struct __attribute__((packed, aligned(4))) ExceptionRaiseRequest { | 80 struct __attribute__((packed, aligned(4))) ExceptionRaiseRequest { |
| 80 ExceptionRaiseRequest() { | 81 ExceptionRaiseRequest() { |
| 81 memset(this, 0xa5, sizeof(*this)); | 82 memset(this, 0xa5, sizeof(*this)); |
| 82 Head.msgh_bits = | 83 Head.msgh_bits = |
| 83 MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND_ONCE, MACH_MSG_TYPE_PORT_SEND) | | 84 MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND_ONCE, MACH_MSG_TYPE_PORT_SEND) | |
| 84 MACH_MSGH_BITS_COMPLEX; | 85 MACH_MSGH_BITS_COMPLEX; |
| 85 Head.msgh_size = sizeof(*this); | 86 Head.msgh_size = sizeof(*this) - sizeof(trailer); |
| 86 Head.msgh_remote_port = kClientRemotePort; | 87 Head.msgh_remote_port = kClientRemotePort; |
| 87 Head.msgh_local_port = kServerLocalPort; | 88 Head.msgh_local_port = kServerLocalPort; |
| 88 Head.msgh_id = 2401; | 89 Head.msgh_id = 2401; |
| 89 msgh_body.msgh_descriptor_count = 2; | 90 msgh_body.msgh_descriptor_count = 2; |
| 90 InitializeMachMsgPortDescriptor(&thread, kExceptionThreadPort); | 91 InitializeMachMsgPortDescriptor(&thread, kExceptionThreadPort); |
| 91 InitializeMachMsgPortDescriptor(&task, kExceptionTaskPort); | 92 InitializeMachMsgPortDescriptor(&task, kExceptionTaskPort); |
| 92 NDR = NDR_record; | 93 NDR = NDR_record; |
| 93 exception = kExceptionType; | 94 exception = kExceptionType; |
| 94 codeCnt = 2; | 95 codeCnt = 2; |
| 95 code[0] = kTestExceptonCodes[0]; | 96 code[0] = kTestExceptonCodes[0]; |
| 96 code[1] = kTestExceptonCodes[1]; | 97 code[1] = kTestExceptonCodes[1]; |
| 97 } | 98 } |
| 98 | 99 |
| 99 mach_msg_header_t Head; | 100 mach_msg_header_t Head; |
| 100 mach_msg_body_t msgh_body; | 101 mach_msg_body_t msgh_body; |
| 101 mach_msg_port_descriptor_t thread; | 102 mach_msg_port_descriptor_t thread; |
| 102 mach_msg_port_descriptor_t task; | 103 mach_msg_port_descriptor_t task; |
| 103 NDR_record_t NDR; | 104 NDR_record_t NDR; |
| 104 exception_type_t exception; | 105 exception_type_t exception; |
| 105 mach_msg_type_number_t codeCnt; | 106 mach_msg_type_number_t codeCnt; |
| 106 integer_t code[2]; | 107 integer_t code[2]; |
| 108 mach_msg_trailer_t trailer; |
| 107 }; | 109 }; |
| 108 | 110 |
| 109 struct __attribute__((packed, aligned(4))) ExceptionRaiseReply { | 111 struct __attribute__((packed, aligned(4))) ExceptionRaiseReply { |
| 110 ExceptionRaiseReply() { | 112 ExceptionRaiseReply() { |
| 111 memset(this, 0x5a, sizeof(*this)); | 113 memset(this, 0x5a, sizeof(*this)); |
| 112 RetCode = KERN_FAILURE; | 114 RetCode = KERN_FAILURE; |
| 113 } | 115 } |
| 114 | 116 |
| 115 // Verify accepts a |behavior| parameter because the same message format and | 117 // Verify accepts a |behavior| parameter because the same message format and |
| 116 // verification function is used for ExceptionRaiseReply and | 118 // verification function is used for ExceptionRaiseReply and |
| (...skipping 25 matching lines...) Expand all Loading... |
| 142 mach_msg_header_t Head; | 144 mach_msg_header_t Head; |
| 143 NDR_record_t NDR; | 145 NDR_record_t NDR; |
| 144 kern_return_t RetCode; | 146 kern_return_t RetCode; |
| 145 }; | 147 }; |
| 146 | 148 |
| 147 struct __attribute__((packed, aligned(4))) ExceptionRaiseStateRequest { | 149 struct __attribute__((packed, aligned(4))) ExceptionRaiseStateRequest { |
| 148 ExceptionRaiseStateRequest() { | 150 ExceptionRaiseStateRequest() { |
| 149 memset(this, 0xa5, sizeof(*this)); | 151 memset(this, 0xa5, sizeof(*this)); |
| 150 Head.msgh_bits = | 152 Head.msgh_bits = |
| 151 MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND_ONCE, MACH_MSG_TYPE_PORT_SEND); | 153 MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND_ONCE, MACH_MSG_TYPE_PORT_SEND); |
| 152 Head.msgh_size = sizeof(*this); | 154 Head.msgh_size = sizeof(*this) - sizeof(trailer); |
| 153 Head.msgh_remote_port = kClientRemotePort; | 155 Head.msgh_remote_port = kClientRemotePort; |
| 154 Head.msgh_local_port = kServerLocalPort; | 156 Head.msgh_local_port = kServerLocalPort; |
| 155 Head.msgh_id = 2402; | 157 Head.msgh_id = 2402; |
| 156 NDR = NDR_record; | 158 NDR = NDR_record; |
| 157 exception = kExceptionType; | 159 exception = kExceptionType; |
| 158 codeCnt = 2; | 160 codeCnt = 2; |
| 159 code[0] = kTestExceptonCodes[0]; | 161 code[0] = kTestExceptonCodes[0]; |
| 160 code[1] = kTestExceptonCodes[1]; | 162 code[1] = kTestExceptonCodes[1]; |
| 161 flavor = kThreadStateFlavor; | 163 flavor = kThreadStateFlavor; |
| 162 old_stateCnt = kThreadStateFlavorCount; | 164 old_stateCnt = kThreadStateFlavorCount; |
| 163 | 165 |
| 164 // Adjust the message size for the data that it’s actually carrying, which | 166 // Adjust the message size for the data that it’s actually carrying, which |
| 165 // may be smaller than the maximum that it can carry. | 167 // may be smaller than the maximum that it can carry. |
| 166 Head.msgh_size += sizeof(old_state[0]) * old_stateCnt - sizeof(old_state); | 168 Head.msgh_size += sizeof(old_state[0]) * old_stateCnt - sizeof(old_state); |
| 167 } | 169 } |
| 168 | 170 |
| 171 // Because the message size has been adjusted, the trailer may not appear in |
| 172 // its home member variable. This computes the actual address of the trailer. |
| 173 const mach_msg_trailer_t* Trailer() const { |
| 174 return MachMessageTrailerFromHeader(&Head); |
| 175 } |
| 176 |
| 169 mach_msg_header_t Head; | 177 mach_msg_header_t Head; |
| 170 NDR_record_t NDR; | 178 NDR_record_t NDR; |
| 171 exception_type_t exception; | 179 exception_type_t exception; |
| 172 mach_msg_type_number_t codeCnt; | 180 mach_msg_type_number_t codeCnt; |
| 173 integer_t code[2]; | 181 integer_t code[2]; |
| 174 int flavor; | 182 int flavor; |
| 175 mach_msg_type_number_t old_stateCnt; | 183 mach_msg_type_number_t old_stateCnt; |
| 176 natural_t old_state[THREAD_STATE_MAX]; | 184 natural_t old_state[THREAD_STATE_MAX]; |
| 185 mach_msg_trailer_t trailer; |
| 177 }; | 186 }; |
| 178 | 187 |
| 179 struct __attribute__((packed, aligned(4))) ExceptionRaiseStateReply { | 188 struct __attribute__((packed, aligned(4))) ExceptionRaiseStateReply { |
| 180 ExceptionRaiseStateReply() { | 189 ExceptionRaiseStateReply() { |
| 181 memset(this, 0x5a, sizeof(*this)); | 190 memset(this, 0x5a, sizeof(*this)); |
| 182 RetCode = KERN_FAILURE; | 191 RetCode = KERN_FAILURE; |
| 183 } | 192 } |
| 184 | 193 |
| 185 // Verify accepts a |behavior| parameter because the same message format and | 194 // Verify accepts a |behavior| parameter because the same message format and |
| 186 // verification function is used for ExceptionRaiseStateReply, | 195 // verification function is used for ExceptionRaiseStateReply, |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 225 mach_msg_type_number_t new_stateCnt; | 234 mach_msg_type_number_t new_stateCnt; |
| 226 natural_t new_state[THREAD_STATE_MAX]; | 235 natural_t new_state[THREAD_STATE_MAX]; |
| 227 }; | 236 }; |
| 228 | 237 |
| 229 struct __attribute__((packed, aligned(4))) ExceptionRaiseStateIdentityRequest { | 238 struct __attribute__((packed, aligned(4))) ExceptionRaiseStateIdentityRequest { |
| 230 ExceptionRaiseStateIdentityRequest() { | 239 ExceptionRaiseStateIdentityRequest() { |
| 231 memset(this, 0xa5, sizeof(*this)); | 240 memset(this, 0xa5, sizeof(*this)); |
| 232 Head.msgh_bits = | 241 Head.msgh_bits = |
| 233 MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND_ONCE, MACH_MSG_TYPE_PORT_SEND) | | 242 MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND_ONCE, MACH_MSG_TYPE_PORT_SEND) | |
| 234 MACH_MSGH_BITS_COMPLEX; | 243 MACH_MSGH_BITS_COMPLEX; |
| 235 Head.msgh_size = sizeof(*this); | 244 Head.msgh_size = sizeof(*this) - sizeof(trailer); |
| 236 Head.msgh_remote_port = kClientRemotePort; | 245 Head.msgh_remote_port = kClientRemotePort; |
| 237 Head.msgh_local_port = kServerLocalPort; | 246 Head.msgh_local_port = kServerLocalPort; |
| 238 Head.msgh_id = 2403; | 247 Head.msgh_id = 2403; |
| 239 msgh_body.msgh_descriptor_count = 2; | 248 msgh_body.msgh_descriptor_count = 2; |
| 240 InitializeMachMsgPortDescriptor(&thread, kExceptionThreadPort); | 249 InitializeMachMsgPortDescriptor(&thread, kExceptionThreadPort); |
| 241 InitializeMachMsgPortDescriptor(&task, kExceptionTaskPort); | 250 InitializeMachMsgPortDescriptor(&task, kExceptionTaskPort); |
| 242 NDR = NDR_record; | 251 NDR = NDR_record; |
| 243 exception = kExceptionType; | 252 exception = kExceptionType; |
| 244 codeCnt = 2; | 253 codeCnt = 2; |
| 245 code[0] = kTestExceptonCodes[0]; | 254 code[0] = kTestExceptonCodes[0]; |
| 246 code[1] = kTestExceptonCodes[1]; | 255 code[1] = kTestExceptonCodes[1]; |
| 247 flavor = kThreadStateFlavor; | 256 flavor = kThreadStateFlavor; |
| 248 old_stateCnt = kThreadStateFlavorCount; | 257 old_stateCnt = kThreadStateFlavorCount; |
| 249 | 258 |
| 250 // Adjust the message size for the data that it’s actually carrying, which | 259 // Adjust the message size for the data that it’s actually carrying, which |
| 251 // may be smaller than the maximum that it can carry. | 260 // may be smaller than the maximum that it can carry. |
| 252 Head.msgh_size += sizeof(old_state[0]) * old_stateCnt - sizeof(old_state); | 261 Head.msgh_size += sizeof(old_state[0]) * old_stateCnt - sizeof(old_state); |
| 253 } | 262 } |
| 254 | 263 |
| 264 // Because the message size has been adjusted, the trailer may not appear in |
| 265 // its home member variable. This computes the actual address of the trailer. |
| 266 const mach_msg_trailer_t* Trailer() const { |
| 267 return MachMessageTrailerFromHeader(&Head); |
| 268 } |
| 269 |
| 255 mach_msg_header_t Head; | 270 mach_msg_header_t Head; |
| 256 mach_msg_body_t msgh_body; | 271 mach_msg_body_t msgh_body; |
| 257 mach_msg_port_descriptor_t thread; | 272 mach_msg_port_descriptor_t thread; |
| 258 mach_msg_port_descriptor_t task; | 273 mach_msg_port_descriptor_t task; |
| 259 NDR_record_t NDR; | 274 NDR_record_t NDR; |
| 260 exception_type_t exception; | 275 exception_type_t exception; |
| 261 mach_msg_type_number_t codeCnt; | 276 mach_msg_type_number_t codeCnt; |
| 262 integer_t code[2]; | 277 integer_t code[2]; |
| 263 int flavor; | 278 int flavor; |
| 264 mach_msg_type_number_t old_stateCnt; | 279 mach_msg_type_number_t old_stateCnt; |
| 265 natural_t old_state[THREAD_STATE_MAX]; | 280 natural_t old_state[THREAD_STATE_MAX]; |
| 281 mach_msg_trailer_t trailer; |
| 266 }; | 282 }; |
| 267 | 283 |
| 268 // The reply messages for exception_raise_state and | 284 // The reply messages for exception_raise_state and |
| 269 // exception_raise_state_identity are identical. | 285 // exception_raise_state_identity are identical. |
| 270 using ExceptionRaiseStateIdentityReply = ExceptionRaiseStateReply; | 286 using ExceptionRaiseStateIdentityReply = ExceptionRaiseStateReply; |
| 271 | 287 |
| 272 struct __attribute__((packed, aligned(4))) MachExceptionRaiseRequest { | 288 struct __attribute__((packed, aligned(4))) MachExceptionRaiseRequest { |
| 273 MachExceptionRaiseRequest() { | 289 MachExceptionRaiseRequest() { |
| 274 memset(this, 0xa5, sizeof(*this)); | 290 memset(this, 0xa5, sizeof(*this)); |
| 275 Head.msgh_bits = | 291 Head.msgh_bits = |
| 276 MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND_ONCE, MACH_MSG_TYPE_PORT_SEND) | | 292 MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND_ONCE, MACH_MSG_TYPE_PORT_SEND) | |
| 277 MACH_MSGH_BITS_COMPLEX; | 293 MACH_MSGH_BITS_COMPLEX; |
| 278 Head.msgh_size = sizeof(*this); | 294 Head.msgh_size = sizeof(*this) - sizeof(trailer); |
| 279 Head.msgh_remote_port = kClientRemotePort; | 295 Head.msgh_remote_port = kClientRemotePort; |
| 280 Head.msgh_local_port = kServerLocalPort; | 296 Head.msgh_local_port = kServerLocalPort; |
| 281 Head.msgh_id = 2405; | 297 Head.msgh_id = 2405; |
| 282 msgh_body.msgh_descriptor_count = 2; | 298 msgh_body.msgh_descriptor_count = 2; |
| 283 InitializeMachMsgPortDescriptor(&thread, kExceptionThreadPort); | 299 InitializeMachMsgPortDescriptor(&thread, kExceptionThreadPort); |
| 284 InitializeMachMsgPortDescriptor(&task, kExceptionTaskPort); | 300 InitializeMachMsgPortDescriptor(&task, kExceptionTaskPort); |
| 285 NDR = NDR_record; | 301 NDR = NDR_record; |
| 286 exception = kExceptionType; | 302 exception = kExceptionType; |
| 287 codeCnt = 2; | 303 codeCnt = 2; |
| 288 code[0] = kTestMachExceptionCodes[0]; | 304 code[0] = kTestMachExceptionCodes[0]; |
| 289 code[1] = kTestMachExceptionCodes[1]; | 305 code[1] = kTestMachExceptionCodes[1]; |
| 290 } | 306 } |
| 291 | 307 |
| 292 mach_msg_header_t Head; | 308 mach_msg_header_t Head; |
| 293 mach_msg_body_t msgh_body; | 309 mach_msg_body_t msgh_body; |
| 294 mach_msg_port_descriptor_t thread; | 310 mach_msg_port_descriptor_t thread; |
| 295 mach_msg_port_descriptor_t task; | 311 mach_msg_port_descriptor_t task; |
| 296 NDR_record_t NDR; | 312 NDR_record_t NDR; |
| 297 exception_type_t exception; | 313 exception_type_t exception; |
| 298 mach_msg_type_number_t codeCnt; | 314 mach_msg_type_number_t codeCnt; |
| 299 int64_t code[2]; | 315 int64_t code[2]; |
| 316 mach_msg_trailer_t trailer; |
| 300 }; | 317 }; |
| 301 | 318 |
| 302 // The reply messages for exception_raise and mach_exception_raise are | 319 // The reply messages for exception_raise and mach_exception_raise are |
| 303 // identical. | 320 // identical. |
| 304 using MachExceptionRaiseReply = ExceptionRaiseReply; | 321 using MachExceptionRaiseReply = ExceptionRaiseReply; |
| 305 | 322 |
| 306 struct __attribute__((packed, aligned(4))) MachExceptionRaiseStateRequest { | 323 struct __attribute__((packed, aligned(4))) MachExceptionRaiseStateRequest { |
| 307 MachExceptionRaiseStateRequest() { | 324 MachExceptionRaiseStateRequest() { |
| 308 memset(this, 0xa5, sizeof(*this)); | 325 memset(this, 0xa5, sizeof(*this)); |
| 309 Head.msgh_bits = | 326 Head.msgh_bits = |
| 310 MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND_ONCE, MACH_MSG_TYPE_PORT_SEND); | 327 MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND_ONCE, MACH_MSG_TYPE_PORT_SEND); |
| 311 Head.msgh_size = sizeof(*this); | 328 Head.msgh_size = sizeof(*this) - sizeof(trailer); |
| 312 Head.msgh_remote_port = kClientRemotePort; | 329 Head.msgh_remote_port = kClientRemotePort; |
| 313 Head.msgh_local_port = kServerLocalPort; | 330 Head.msgh_local_port = kServerLocalPort; |
| 314 Head.msgh_id = 2406; | 331 Head.msgh_id = 2406; |
| 315 NDR = NDR_record; | 332 NDR = NDR_record; |
| 316 exception = kExceptionType; | 333 exception = kExceptionType; |
| 317 codeCnt = 2; | 334 codeCnt = 2; |
| 318 code[0] = kTestMachExceptionCodes[0]; | 335 code[0] = kTestMachExceptionCodes[0]; |
| 319 code[1] = kTestMachExceptionCodes[1]; | 336 code[1] = kTestMachExceptionCodes[1]; |
| 320 flavor = kThreadStateFlavor; | 337 flavor = kThreadStateFlavor; |
| 321 old_stateCnt = kThreadStateFlavorCount; | 338 old_stateCnt = kThreadStateFlavorCount; |
| 322 | 339 |
| 323 // Adjust the message size for the data that it’s actually carrying, which | 340 // Adjust the message size for the data that it’s actually carrying, which |
| 324 // may be smaller than the maximum that it can carry. | 341 // may be smaller than the maximum that it can carry. |
| 325 Head.msgh_size += sizeof(old_state[0]) * old_stateCnt - sizeof(old_state); | 342 Head.msgh_size += sizeof(old_state[0]) * old_stateCnt - sizeof(old_state); |
| 326 } | 343 } |
| 327 | 344 |
| 345 // Because the message size has been adjusted, the trailer may not appear in |
| 346 // its home member variable. This computes the actual address of the trailer. |
| 347 const mach_msg_trailer_t* Trailer() const { |
| 348 return MachMessageTrailerFromHeader(&Head); |
| 349 } |
| 350 |
| 328 mach_msg_header_t Head; | 351 mach_msg_header_t Head; |
| 329 NDR_record_t NDR; | 352 NDR_record_t NDR; |
| 330 exception_type_t exception; | 353 exception_type_t exception; |
| 331 mach_msg_type_number_t codeCnt; | 354 mach_msg_type_number_t codeCnt; |
| 332 int64_t code[2]; | 355 int64_t code[2]; |
| 333 int flavor; | 356 int flavor; |
| 334 mach_msg_type_number_t old_stateCnt; | 357 mach_msg_type_number_t old_stateCnt; |
| 335 natural_t old_state[THREAD_STATE_MAX]; | 358 natural_t old_state[THREAD_STATE_MAX]; |
| 359 mach_msg_trailer_t trailer; |
| 336 }; | 360 }; |
| 337 | 361 |
| 338 // The reply messages for exception_raise_state and mach_exception_raise_state | 362 // The reply messages for exception_raise_state and mach_exception_raise_state |
| 339 // are identical. | 363 // are identical. |
| 340 using MachExceptionRaiseStateReply = ExceptionRaiseStateReply; | 364 using MachExceptionRaiseStateReply = ExceptionRaiseStateReply; |
| 341 | 365 |
| 342 struct __attribute__((packed, | 366 struct __attribute__((packed, |
| 343 aligned(4))) MachExceptionRaiseStateIdentityRequest { | 367 aligned(4))) MachExceptionRaiseStateIdentityRequest { |
| 344 MachExceptionRaiseStateIdentityRequest() { | 368 MachExceptionRaiseStateIdentityRequest() { |
| 345 memset(this, 0xa5, sizeof(*this)); | 369 memset(this, 0xa5, sizeof(*this)); |
| 346 Head.msgh_bits = | 370 Head.msgh_bits = |
| 347 MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND_ONCE, MACH_MSG_TYPE_PORT_SEND) | | 371 MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND_ONCE, MACH_MSG_TYPE_PORT_SEND) | |
| 348 MACH_MSGH_BITS_COMPLEX; | 372 MACH_MSGH_BITS_COMPLEX; |
| 349 Head.msgh_size = sizeof(*this); | 373 Head.msgh_size = sizeof(*this) - sizeof(trailer); |
| 350 Head.msgh_remote_port = kClientRemotePort; | 374 Head.msgh_remote_port = kClientRemotePort; |
| 351 Head.msgh_local_port = kServerLocalPort; | 375 Head.msgh_local_port = kServerLocalPort; |
| 352 Head.msgh_id = 2407; | 376 Head.msgh_id = 2407; |
| 353 msgh_body.msgh_descriptor_count = 2; | 377 msgh_body.msgh_descriptor_count = 2; |
| 354 InitializeMachMsgPortDescriptor(&thread, kExceptionThreadPort); | 378 InitializeMachMsgPortDescriptor(&thread, kExceptionThreadPort); |
| 355 InitializeMachMsgPortDescriptor(&task, kExceptionTaskPort); | 379 InitializeMachMsgPortDescriptor(&task, kExceptionTaskPort); |
| 356 NDR = NDR_record; | 380 NDR = NDR_record; |
| 357 exception = kExceptionType; | 381 exception = kExceptionType; |
| 358 codeCnt = 2; | 382 codeCnt = 2; |
| 359 code[0] = kTestMachExceptionCodes[0]; | 383 code[0] = kTestMachExceptionCodes[0]; |
| 360 code[1] = kTestMachExceptionCodes[1]; | 384 code[1] = kTestMachExceptionCodes[1]; |
| 361 flavor = kThreadStateFlavor; | 385 flavor = kThreadStateFlavor; |
| 362 old_stateCnt = kThreadStateFlavorCount; | 386 old_stateCnt = kThreadStateFlavorCount; |
| 363 | 387 |
| 364 // Adjust the message size for the data that it’s actually carrying, which | 388 // Adjust the message size for the data that it’s actually carrying, which |
| 365 // may be smaller than the maximum that it can carry. | 389 // may be smaller than the maximum that it can carry. |
| 366 Head.msgh_size += sizeof(old_state[0]) * old_stateCnt - sizeof(old_state); | 390 Head.msgh_size += sizeof(old_state[0]) * old_stateCnt - sizeof(old_state); |
| 367 } | 391 } |
| 368 | 392 |
| 393 // Because the message size has been adjusted, the trailer may not appear in |
| 394 // its home member variable. This computes the actual address of the trailer. |
| 395 const mach_msg_trailer_t* Trailer() const { |
| 396 return MachMessageTrailerFromHeader(&Head); |
| 397 } |
| 398 |
| 369 mach_msg_header_t Head; | 399 mach_msg_header_t Head; |
| 370 mach_msg_body_t msgh_body; | 400 mach_msg_body_t msgh_body; |
| 371 mach_msg_port_descriptor_t thread; | 401 mach_msg_port_descriptor_t thread; |
| 372 mach_msg_port_descriptor_t task; | 402 mach_msg_port_descriptor_t task; |
| 373 NDR_record_t NDR; | 403 NDR_record_t NDR; |
| 374 exception_type_t exception; | 404 exception_type_t exception; |
| 375 mach_msg_type_number_t codeCnt; | 405 mach_msg_type_number_t codeCnt; |
| 376 int64_t code[2]; | 406 int64_t code[2]; |
| 377 int flavor; | 407 int flavor; |
| 378 mach_msg_type_number_t old_stateCnt; | 408 mach_msg_type_number_t old_stateCnt; |
| 379 natural_t old_state[THREAD_STATE_MAX]; | 409 natural_t old_state[THREAD_STATE_MAX]; |
| 410 mach_msg_trailer_t trailer; |
| 380 }; | 411 }; |
| 381 | 412 |
| 382 // The reply messages for exception_raise_state_identity and | 413 // The reply messages for exception_raise_state_identity and |
| 383 // mach_exception_raise_state_identity are identical. | 414 // mach_exception_raise_state_identity are identical. |
| 384 using MachExceptionRaiseStateIdentityReply = ExceptionRaiseStateIdentityReply; | 415 using MachExceptionRaiseStateIdentityReply = ExceptionRaiseStateIdentityReply; |
| 385 | 416 |
| 386 // InvalidRequest and BadIDErrorReply are used to test that | 417 // InvalidRequest and BadIDErrorReply are used to test that |
| 387 // UniversalMachExcServer deals appropriately with messages that it does not | 418 // UniversalMachExcServer deals appropriately with messages that it does not |
| 388 // understand: messages with an unknown Head.msgh_id. | 419 // understand: messages with an unknown Head.msgh_id. |
| 389 | 420 |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 442 thread_t thread, | 473 thread_t thread, |
| 443 task_t task, | 474 task_t task, |
| 444 exception_type_t exception, | 475 exception_type_t exception, |
| 445 const mach_exception_data_type_t* code, | 476 const mach_exception_data_type_t* code, |
| 446 mach_msg_type_number_t code_count, | 477 mach_msg_type_number_t code_count, |
| 447 thread_state_flavor_t* flavor, | 478 thread_state_flavor_t* flavor, |
| 448 const natural_t* old_state, | 479 const natural_t* old_state, |
| 449 mach_msg_type_number_t old_state_count, | 480 mach_msg_type_number_t old_state_count, |
| 450 thread_state_t new_state, | 481 thread_state_t new_state, |
| 451 mach_msg_type_number_t* new_state_count, | 482 mach_msg_type_number_t* new_state_count, |
| 483 const mach_msg_trailer_t* trailer, |
| 452 bool* destroy_complex_request) override { | 484 bool* destroy_complex_request) override { |
| 453 *destroy_complex_request = true; | 485 *destroy_complex_request = true; |
| 454 const ConstExceptionCodes exception_codes = {code, code_count}; | 486 const ConstExceptionCodes exception_codes = {code, code_count}; |
| 455 const ConstThreadState old_thread_state = {old_state, &old_state_count}; | 487 const ConstThreadState old_thread_state = {old_state, &old_state_count}; |
| 456 ThreadState new_thread_state = {new_state, new_state_count}; | 488 ThreadState new_thread_state = {new_state, new_state_count}; |
| 457 return MockCatchMachException(behavior, | 489 return MockCatchMachException(behavior, |
| 458 exception_port, | 490 exception_port, |
| 459 thread, | 491 thread, |
| 460 task, | 492 task, |
| 461 exception, | 493 exception, |
| 462 &exception_codes, | 494 &exception_codes, |
| 463 flavor, | 495 flavor, |
| 464 &old_thread_state, | 496 &old_thread_state, |
| 465 &new_thread_state); | 497 &new_thread_state, |
| 498 trailer); |
| 466 } | 499 } |
| 467 | 500 |
| 468 MOCK_METHOD9(MockCatchMachException, | 501 MOCK_METHOD10(MockCatchMachException, |
| 469 kern_return_t(exception_behavior_t behavior, | 502 kern_return_t(exception_behavior_t behavior, |
| 470 exception_handler_t exception_port, | 503 exception_handler_t exception_port, |
| 471 thread_t thread, | 504 thread_t thread, |
| 472 task_t task, | 505 task_t task, |
| 473 exception_type_t exception, | 506 exception_type_t exception, |
| 474 const ConstExceptionCodes* exception_codes, | 507 const ConstExceptionCodes* exception_codes, |
| 475 thread_state_flavor_t* flavor, | 508 thread_state_flavor_t* flavor, |
| 476 const ConstThreadState* old_thread_state, | 509 const ConstThreadState* old_thread_state, |
| 477 ThreadState* new_thread_state)); | 510 ThreadState* new_thread_state, |
| 511 const mach_msg_trailer_t* trailer)); |
| 478 }; | 512 }; |
| 479 | 513 |
| 480 // Matcher for ConstExceptionCodes, testing that it carries 2 codes matching | 514 // Matcher for ConstExceptionCodes, testing that it carries 2 codes matching |
| 481 // code_0 and code_1. | 515 // code_0 and code_1. |
| 482 MATCHER_P2(AreExceptionCodes, code_0, code_1, "") { | 516 MATCHER_P2(AreExceptionCodes, code_0, code_1, "") { |
| 483 if (!arg) { | 517 if (!arg) { |
| 484 return false; | 518 return false; |
| 485 } | 519 } |
| 486 | 520 |
| 487 if (arg->code_count == 2 && arg->code[0] == code_0 && | 521 if (arg->code_count == 2 && arg->code[0] == code_0 && |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 541 | 575 |
| 542 ~ScopedDefaultValue() { DefaultValue<T>::Clear(); } | 576 ~ScopedDefaultValue() { DefaultValue<T>::Clear(); } |
| 543 }; | 577 }; |
| 544 | 578 |
| 545 TEST(ExcServerVariants, MockExceptionRaise) { | 579 TEST(ExcServerVariants, MockExceptionRaise) { |
| 546 ScopedDefaultValue<kern_return_t> default_kern_return_t(KERN_FAILURE); | 580 ScopedDefaultValue<kern_return_t> default_kern_return_t(KERN_FAILURE); |
| 547 | 581 |
| 548 MockUniversalMachExcServer server; | 582 MockUniversalMachExcServer server; |
| 549 | 583 |
| 550 ExceptionRaiseRequest request; | 584 ExceptionRaiseRequest request; |
| 551 EXPECT_LE(sizeof(request), server.MachMessageServerRequestSize()); | 585 EXPECT_LE(request.Head.msgh_size, server.MachMessageServerRequestSize()); |
| 552 | 586 |
| 553 ExceptionRaiseReply reply; | 587 ExceptionRaiseReply reply; |
| 554 EXPECT_LE(sizeof(reply), server.MachMessageServerReplySize()); | 588 EXPECT_LE(sizeof(reply), server.MachMessageServerReplySize()); |
| 555 | 589 |
| 556 const exception_behavior_t kExceptionBehavior = EXCEPTION_DEFAULT; | 590 const exception_behavior_t kExceptionBehavior = EXCEPTION_DEFAULT; |
| 557 | 591 |
| 558 EXPECT_CALL(server, | 592 EXPECT_CALL(server, |
| 559 MockCatchMachException(kExceptionBehavior, | 593 MockCatchMachException(kExceptionBehavior, |
| 560 kServerLocalPort, | 594 kServerLocalPort, |
| 561 kExceptionThreadPort, | 595 kExceptionThreadPort, |
| 562 kExceptionTaskPort, | 596 kExceptionTaskPort, |
| 563 kExceptionType, | 597 kExceptionType, |
| 564 AreExceptionCodes(kTestExceptonCodes[0], | 598 AreExceptionCodes(kTestExceptonCodes[0], |
| 565 kTestExceptonCodes[1]), | 599 kTestExceptonCodes[1]), |
| 566 Pointee(Eq(THREAD_STATE_NONE)), | 600 Pointee(Eq(THREAD_STATE_NONE)), |
| 567 IsThreadStateCount(0u), | 601 IsThreadStateCount(0u), |
| 568 IsThreadStateCount(0u))) | 602 IsThreadStateCount(0u), |
| 603 Eq(&request.trailer))) |
| 569 .WillOnce(Return(KERN_SUCCESS)) | 604 .WillOnce(Return(KERN_SUCCESS)) |
| 570 .RetiresOnSaturation(); | 605 .RetiresOnSaturation(); |
| 571 | 606 |
| 572 bool destroy_complex_request = false; | 607 bool destroy_complex_request = false; |
| 573 EXPECT_TRUE(server.MachMessageServerFunction( | 608 EXPECT_TRUE(server.MachMessageServerFunction( |
| 574 reinterpret_cast<mach_msg_header_t*>(&request), | 609 reinterpret_cast<mach_msg_header_t*>(&request), |
| 575 reinterpret_cast<mach_msg_header_t*>(&reply), | 610 reinterpret_cast<mach_msg_header_t*>(&reply), |
| 576 &destroy_complex_request)); | 611 &destroy_complex_request)); |
| 577 EXPECT_TRUE(destroy_complex_request); | 612 EXPECT_TRUE(destroy_complex_request); |
| 578 | 613 |
| 579 reply.Verify(kExceptionBehavior); | 614 reply.Verify(kExceptionBehavior); |
| 580 } | 615 } |
| 581 | 616 |
| 582 TEST(ExcServerVariants, MockExceptionRaiseState) { | 617 TEST(ExcServerVariants, MockExceptionRaiseState) { |
| 583 ScopedDefaultValue<kern_return_t> default_kern_return_t(KERN_FAILURE); | 618 ScopedDefaultValue<kern_return_t> default_kern_return_t(KERN_FAILURE); |
| 584 | 619 |
| 585 MockUniversalMachExcServer server; | 620 MockUniversalMachExcServer server; |
| 586 | 621 |
| 587 ExceptionRaiseStateRequest request; | 622 ExceptionRaiseStateRequest request; |
| 588 EXPECT_LE(sizeof(request), server.MachMessageServerRequestSize()); | 623 EXPECT_LE(request.Head.msgh_size, server.MachMessageServerRequestSize()); |
| 589 | 624 |
| 590 ExceptionRaiseStateReply reply; | 625 ExceptionRaiseStateReply reply; |
| 591 EXPECT_LE(sizeof(reply), server.MachMessageServerReplySize()); | 626 EXPECT_LE(sizeof(reply), server.MachMessageServerReplySize()); |
| 592 | 627 |
| 593 const exception_behavior_t kExceptionBehavior = EXCEPTION_STATE; | 628 const exception_behavior_t kExceptionBehavior = EXCEPTION_STATE; |
| 594 | 629 |
| 595 EXPECT_CALL( | 630 EXPECT_CALL( |
| 596 server, | 631 server, |
| 597 MockCatchMachException( | 632 MockCatchMachException( |
| 598 kExceptionBehavior, | 633 kExceptionBehavior, |
| 599 kServerLocalPort, | 634 kServerLocalPort, |
| 600 THREAD_NULL, | 635 THREAD_NULL, |
| 601 TASK_NULL, | 636 TASK_NULL, |
| 602 kExceptionType, | 637 kExceptionType, |
| 603 AreExceptionCodes(kTestExceptonCodes[0], kTestExceptonCodes[1]), | 638 AreExceptionCodes(kTestExceptonCodes[0], kTestExceptonCodes[1]), |
| 604 Pointee(Eq(kThreadStateFlavor)), | 639 Pointee(Eq(kThreadStateFlavor)), |
| 605 IsThreadStateCount(kThreadStateFlavorCount), | 640 IsThreadStateCount(kThreadStateFlavorCount), |
| 606 IsThreadStateCount(arraysize(reply.new_state)))) | 641 IsThreadStateCount(arraysize(reply.new_state)), |
| 642 Eq(request.Trailer()))) |
| 607 .WillOnce(Return(KERN_SUCCESS)) | 643 .WillOnce(Return(KERN_SUCCESS)) |
| 608 .RetiresOnSaturation(); | 644 .RetiresOnSaturation(); |
| 609 | 645 |
| 610 bool destroy_complex_request = false; | 646 bool destroy_complex_request = false; |
| 611 EXPECT_TRUE(server.MachMessageServerFunction( | 647 EXPECT_TRUE(server.MachMessageServerFunction( |
| 612 reinterpret_cast<mach_msg_header_t*>(&request), | 648 reinterpret_cast<mach_msg_header_t*>(&request), |
| 613 reinterpret_cast<mach_msg_header_t*>(&reply), | 649 reinterpret_cast<mach_msg_header_t*>(&reply), |
| 614 &destroy_complex_request)); | 650 &destroy_complex_request)); |
| 615 | 651 |
| 616 // The request wasn’t complex, so nothing got a chance to change the value of | 652 // The request wasn’t complex, so nothing got a chance to change the value of |
| 617 // this variable. | 653 // this variable. |
| 618 EXPECT_FALSE(destroy_complex_request); | 654 EXPECT_FALSE(destroy_complex_request); |
| 619 | 655 |
| 620 reply.Verify(kExceptionBehavior); | 656 reply.Verify(kExceptionBehavior); |
| 621 } | 657 } |
| 622 | 658 |
| 623 TEST(ExcServerVariants, MockExceptionRaiseStateIdentity) { | 659 TEST(ExcServerVariants, MockExceptionRaiseStateIdentity) { |
| 624 ScopedDefaultValue<kern_return_t> default_kern_return_t(KERN_FAILURE); | 660 ScopedDefaultValue<kern_return_t> default_kern_return_t(KERN_FAILURE); |
| 625 | 661 |
| 626 MockUniversalMachExcServer server; | 662 MockUniversalMachExcServer server; |
| 627 | 663 |
| 628 ExceptionRaiseStateIdentityRequest request; | 664 ExceptionRaiseStateIdentityRequest request; |
| 629 EXPECT_LE(sizeof(request), server.MachMessageServerRequestSize()); | 665 EXPECT_LE(request.Head.msgh_size, server.MachMessageServerRequestSize()); |
| 630 | 666 |
| 631 ExceptionRaiseStateIdentityReply reply; | 667 ExceptionRaiseStateIdentityReply reply; |
| 632 EXPECT_LE(sizeof(reply), server.MachMessageServerReplySize()); | 668 EXPECT_LE(sizeof(reply), server.MachMessageServerReplySize()); |
| 633 | 669 |
| 634 const exception_behavior_t kExceptionBehavior = EXCEPTION_STATE_IDENTITY; | 670 const exception_behavior_t kExceptionBehavior = EXCEPTION_STATE_IDENTITY; |
| 635 | 671 |
| 636 EXPECT_CALL( | 672 EXPECT_CALL( |
| 637 server, | 673 server, |
| 638 MockCatchMachException( | 674 MockCatchMachException( |
| 639 kExceptionBehavior, | 675 kExceptionBehavior, |
| 640 kServerLocalPort, | 676 kServerLocalPort, |
| 641 kExceptionThreadPort, | 677 kExceptionThreadPort, |
| 642 kExceptionTaskPort, | 678 kExceptionTaskPort, |
| 643 kExceptionType, | 679 kExceptionType, |
| 644 AreExceptionCodes(kTestExceptonCodes[0], kTestExceptonCodes[1]), | 680 AreExceptionCodes(kTestExceptonCodes[0], kTestExceptonCodes[1]), |
| 645 Pointee(Eq(kThreadStateFlavor)), | 681 Pointee(Eq(kThreadStateFlavor)), |
| 646 IsThreadStateCount(kThreadStateFlavorCount), | 682 IsThreadStateCount(kThreadStateFlavorCount), |
| 647 IsThreadStateCount(arraysize(reply.new_state)))) | 683 IsThreadStateCount(arraysize(reply.new_state)), |
| 684 Eq(request.Trailer()))) |
| 648 .WillOnce(Return(KERN_SUCCESS)) | 685 .WillOnce(Return(KERN_SUCCESS)) |
| 649 .RetiresOnSaturation(); | 686 .RetiresOnSaturation(); |
| 650 | 687 |
| 651 bool destroy_complex_request = false; | 688 bool destroy_complex_request = false; |
| 652 EXPECT_TRUE(server.MachMessageServerFunction( | 689 EXPECT_TRUE(server.MachMessageServerFunction( |
| 653 reinterpret_cast<mach_msg_header_t*>(&request), | 690 reinterpret_cast<mach_msg_header_t*>(&request), |
| 654 reinterpret_cast<mach_msg_header_t*>(&reply), | 691 reinterpret_cast<mach_msg_header_t*>(&reply), |
| 655 &destroy_complex_request)); | 692 &destroy_complex_request)); |
| 656 EXPECT_TRUE(destroy_complex_request); | 693 EXPECT_TRUE(destroy_complex_request); |
| 657 | 694 |
| 658 reply.Verify(kExceptionBehavior); | 695 reply.Verify(kExceptionBehavior); |
| 659 } | 696 } |
| 660 | 697 |
| 661 TEST(ExcServerVariants, MockMachExceptionRaise) { | 698 TEST(ExcServerVariants, MockMachExceptionRaise) { |
| 662 ScopedDefaultValue<kern_return_t> default_kern_return_t(KERN_FAILURE); | 699 ScopedDefaultValue<kern_return_t> default_kern_return_t(KERN_FAILURE); |
| 663 | 700 |
| 664 MockUniversalMachExcServer server; | 701 MockUniversalMachExcServer server; |
| 665 | 702 |
| 666 MachExceptionRaiseRequest request; | 703 MachExceptionRaiseRequest request; |
| 667 EXPECT_LE(sizeof(request), server.MachMessageServerRequestSize()); | 704 EXPECT_LE(request.Head.msgh_size, server.MachMessageServerRequestSize()); |
| 668 | 705 |
| 669 MachExceptionRaiseReply reply; | 706 MachExceptionRaiseReply reply; |
| 670 EXPECT_LE(sizeof(reply), server.MachMessageServerReplySize()); | 707 EXPECT_LE(sizeof(reply), server.MachMessageServerReplySize()); |
| 671 | 708 |
| 672 const exception_behavior_t kExceptionBehavior = | 709 const exception_behavior_t kExceptionBehavior = |
| 673 EXCEPTION_DEFAULT | MACH_EXCEPTION_CODES; | 710 EXCEPTION_DEFAULT | MACH_EXCEPTION_CODES; |
| 674 | 711 |
| 675 EXPECT_CALL( | 712 EXPECT_CALL( |
| 676 server, | 713 server, |
| 677 MockCatchMachException(kExceptionBehavior, | 714 MockCatchMachException(kExceptionBehavior, |
| 678 kServerLocalPort, | 715 kServerLocalPort, |
| 679 kExceptionThreadPort, | 716 kExceptionThreadPort, |
| 680 kExceptionTaskPort, | 717 kExceptionTaskPort, |
| 681 kExceptionType, | 718 kExceptionType, |
| 682 AreExceptionCodes(kTestMachExceptionCodes[0], | 719 AreExceptionCodes(kTestMachExceptionCodes[0], |
| 683 kTestMachExceptionCodes[1]), | 720 kTestMachExceptionCodes[1]), |
| 684 Pointee(Eq(THREAD_STATE_NONE)), | 721 Pointee(Eq(THREAD_STATE_NONE)), |
| 685 IsThreadStateCount(0u), | 722 IsThreadStateCount(0u), |
| 686 IsThreadStateCount(0u))) | 723 IsThreadStateCount(0u), |
| 724 Eq(&request.trailer))) |
| 687 .WillOnce(Return(KERN_SUCCESS)) | 725 .WillOnce(Return(KERN_SUCCESS)) |
| 688 .RetiresOnSaturation(); | 726 .RetiresOnSaturation(); |
| 689 | 727 |
| 690 bool destroy_complex_request = false; | 728 bool destroy_complex_request = false; |
| 691 EXPECT_TRUE(server.MachMessageServerFunction( | 729 EXPECT_TRUE(server.MachMessageServerFunction( |
| 692 reinterpret_cast<mach_msg_header_t*>(&request), | 730 reinterpret_cast<mach_msg_header_t*>(&request), |
| 693 reinterpret_cast<mach_msg_header_t*>(&reply), | 731 reinterpret_cast<mach_msg_header_t*>(&reply), |
| 694 &destroy_complex_request)); | 732 &destroy_complex_request)); |
| 695 EXPECT_TRUE(destroy_complex_request); | 733 EXPECT_TRUE(destroy_complex_request); |
| 696 | 734 |
| 697 reply.Verify(kExceptionBehavior); | 735 reply.Verify(kExceptionBehavior); |
| 698 } | 736 } |
| 699 | 737 |
| 700 TEST(ExcServerVariants, MockMachExceptionRaiseState) { | 738 TEST(ExcServerVariants, MockMachExceptionRaiseState) { |
| 701 ScopedDefaultValue<kern_return_t> default_kern_return_t(KERN_FAILURE); | 739 ScopedDefaultValue<kern_return_t> default_kern_return_t(KERN_FAILURE); |
| 702 | 740 |
| 703 MockUniversalMachExcServer server; | 741 MockUniversalMachExcServer server; |
| 704 | 742 |
| 705 MachExceptionRaiseStateRequest request; | 743 MachExceptionRaiseStateRequest request; |
| 706 EXPECT_LE(sizeof(request), server.MachMessageServerRequestSize()); | 744 EXPECT_LE(request.Head.msgh_size, server.MachMessageServerRequestSize()); |
| 707 | 745 |
| 708 MachExceptionRaiseStateReply reply; | 746 MachExceptionRaiseStateReply reply; |
| 709 EXPECT_LE(sizeof(reply), server.MachMessageServerReplySize()); | 747 EXPECT_LE(sizeof(reply), server.MachMessageServerReplySize()); |
| 710 | 748 |
| 711 const exception_behavior_t kExceptionBehavior = | 749 const exception_behavior_t kExceptionBehavior = |
| 712 EXCEPTION_STATE | MACH_EXCEPTION_CODES; | 750 EXCEPTION_STATE | MACH_EXCEPTION_CODES; |
| 713 | 751 |
| 714 EXPECT_CALL( | 752 EXPECT_CALL( |
| 715 server, | 753 server, |
| 716 MockCatchMachException(kExceptionBehavior, | 754 MockCatchMachException(kExceptionBehavior, |
| 717 kServerLocalPort, | 755 kServerLocalPort, |
| 718 THREAD_NULL, | 756 THREAD_NULL, |
| 719 TASK_NULL, | 757 TASK_NULL, |
| 720 kExceptionType, | 758 kExceptionType, |
| 721 AreExceptionCodes(kTestMachExceptionCodes[0], | 759 AreExceptionCodes(kTestMachExceptionCodes[0], |
| 722 kTestMachExceptionCodes[1]), | 760 kTestMachExceptionCodes[1]), |
| 723 Pointee(Eq(kThreadStateFlavor)), | 761 Pointee(Eq(kThreadStateFlavor)), |
| 724 IsThreadStateCount(kThreadStateFlavorCount), | 762 IsThreadStateCount(kThreadStateFlavorCount), |
| 725 IsThreadStateCount(arraysize(reply.new_state)))) | 763 IsThreadStateCount(arraysize(reply.new_state)), |
| 764 Eq(request.Trailer()))) |
| 726 .WillOnce(Return(KERN_SUCCESS)) | 765 .WillOnce(Return(KERN_SUCCESS)) |
| 727 .RetiresOnSaturation(); | 766 .RetiresOnSaturation(); |
| 728 | 767 |
| 729 bool destroy_complex_request = false; | 768 bool destroy_complex_request = false; |
| 730 EXPECT_TRUE(server.MachMessageServerFunction( | 769 EXPECT_TRUE(server.MachMessageServerFunction( |
| 731 reinterpret_cast<mach_msg_header_t*>(&request), | 770 reinterpret_cast<mach_msg_header_t*>(&request), |
| 732 reinterpret_cast<mach_msg_header_t*>(&reply), | 771 reinterpret_cast<mach_msg_header_t*>(&reply), |
| 733 &destroy_complex_request)); | 772 &destroy_complex_request)); |
| 734 | 773 |
| 735 // The request wasn’t complex, so nothing got a chance to change the value of | 774 // The request wasn’t complex, so nothing got a chance to change the value of |
| 736 // this variable. | 775 // this variable. |
| 737 EXPECT_FALSE(destroy_complex_request); | 776 EXPECT_FALSE(destroy_complex_request); |
| 738 | 777 |
| 739 reply.Verify(kExceptionBehavior); | 778 reply.Verify(kExceptionBehavior); |
| 740 } | 779 } |
| 741 | 780 |
| 742 TEST(ExcServerVariants, MockMachExceptionRaiseStateIdentity) { | 781 TEST(ExcServerVariants, MockMachExceptionRaiseStateIdentity) { |
| 743 ScopedDefaultValue<kern_return_t> default_kern_return_t(KERN_FAILURE); | 782 ScopedDefaultValue<kern_return_t> default_kern_return_t(KERN_FAILURE); |
| 744 | 783 |
| 745 MockUniversalMachExcServer server; | 784 MockUniversalMachExcServer server; |
| 746 | 785 |
| 747 MachExceptionRaiseStateIdentityRequest request; | 786 MachExceptionRaiseStateIdentityRequest request; |
| 748 EXPECT_LE(sizeof(request), server.MachMessageServerRequestSize()); | 787 EXPECT_LE(request.Head.msgh_size, server.MachMessageServerRequestSize()); |
| 749 | 788 |
| 750 MachExceptionRaiseStateIdentityReply reply; | 789 MachExceptionRaiseStateIdentityReply reply; |
| 751 EXPECT_LE(sizeof(reply), server.MachMessageServerReplySize()); | 790 EXPECT_LE(sizeof(reply), server.MachMessageServerReplySize()); |
| 752 | 791 |
| 753 const exception_behavior_t kExceptionBehavior = | 792 const exception_behavior_t kExceptionBehavior = |
| 754 EXCEPTION_STATE_IDENTITY | MACH_EXCEPTION_CODES; | 793 EXCEPTION_STATE_IDENTITY | MACH_EXCEPTION_CODES; |
| 755 | 794 |
| 756 EXPECT_CALL( | 795 EXPECT_CALL( |
| 757 server, | 796 server, |
| 758 MockCatchMachException(kExceptionBehavior, | 797 MockCatchMachException(kExceptionBehavior, |
| 759 kServerLocalPort, | 798 kServerLocalPort, |
| 760 kExceptionThreadPort, | 799 kExceptionThreadPort, |
| 761 kExceptionTaskPort, | 800 kExceptionTaskPort, |
| 762 kExceptionType, | 801 kExceptionType, |
| 763 AreExceptionCodes(kTestMachExceptionCodes[0], | 802 AreExceptionCodes(kTestMachExceptionCodes[0], |
| 764 kTestMachExceptionCodes[1]), | 803 kTestMachExceptionCodes[1]), |
| 765 Pointee(Eq(kThreadStateFlavor)), | 804 Pointee(Eq(kThreadStateFlavor)), |
| 766 IsThreadStateCount(kThreadStateFlavorCount), | 805 IsThreadStateCount(kThreadStateFlavorCount), |
| 767 IsThreadStateCount(arraysize(reply.new_state)))) | 806 IsThreadStateCount(arraysize(reply.new_state)), |
| 807 Eq(request.Trailer()))) |
| 768 .WillOnce(Return(KERN_SUCCESS)) | 808 .WillOnce(Return(KERN_SUCCESS)) |
| 769 .RetiresOnSaturation(); | 809 .RetiresOnSaturation(); |
| 770 | 810 |
| 771 bool destroy_complex_request = false; | 811 bool destroy_complex_request = false; |
| 772 EXPECT_TRUE(server.MachMessageServerFunction( | 812 EXPECT_TRUE(server.MachMessageServerFunction( |
| 773 reinterpret_cast<mach_msg_header_t*>(&request), | 813 reinterpret_cast<mach_msg_header_t*>(&request), |
| 774 reinterpret_cast<mach_msg_header_t*>(&reply), | 814 reinterpret_cast<mach_msg_header_t*>(&reply), |
| 775 &destroy_complex_request)); | 815 &destroy_complex_request)); |
| 776 EXPECT_TRUE(destroy_complex_request); | 816 EXPECT_TRUE(destroy_complex_request); |
| 777 | 817 |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 864 thread_t thread, | 904 thread_t thread, |
| 865 task_t task, | 905 task_t task, |
| 866 exception_type_t exception, | 906 exception_type_t exception, |
| 867 const mach_exception_data_type_t* code, | 907 const mach_exception_data_type_t* code, |
| 868 mach_msg_type_number_t code_count, | 908 mach_msg_type_number_t code_count, |
| 869 thread_state_flavor_t* flavor, | 909 thread_state_flavor_t* flavor, |
| 870 const natural_t* old_state, | 910 const natural_t* old_state, |
| 871 mach_msg_type_number_t old_state_count, | 911 mach_msg_type_number_t old_state_count, |
| 872 thread_state_t new_state, | 912 thread_state_t new_state, |
| 873 mach_msg_type_number_t* new_state_count, | 913 mach_msg_type_number_t* new_state_count, |
| 914 const mach_msg_trailer_t* trailer, |
| 874 bool* destroy_complex_request) override { | 915 bool* destroy_complex_request) override { |
| 875 *destroy_complex_request = true; | 916 *destroy_complex_request = true; |
| 876 | 917 |
| 877 EXPECT_FALSE(handled_); | 918 EXPECT_FALSE(handled_); |
| 878 handled_ = true; | 919 handled_ = true; |
| 879 | 920 |
| 880 EXPECT_EQ(behavior_, behavior); | 921 EXPECT_EQ(behavior_, behavior); |
| 881 | 922 |
| 882 EXPECT_EQ(LocalPort(), exception_port); | 923 EXPECT_EQ(LocalPort(), exception_port); |
| 883 | 924 |
| (...skipping 26 matching lines...) Expand all Loading... |
| 910 *new_state_count); | 951 *new_state_count); |
| 911 EXPECT_NE(nullptr, new_state); | 952 EXPECT_NE(nullptr, new_state); |
| 912 } else { | 953 } else { |
| 913 EXPECT_EQ(THREAD_STATE_NONE, *flavor); | 954 EXPECT_EQ(THREAD_STATE_NONE, *flavor); |
| 914 EXPECT_EQ(0u, old_state_count); | 955 EXPECT_EQ(0u, old_state_count); |
| 915 EXPECT_EQ(nullptr, old_state); | 956 EXPECT_EQ(nullptr, old_state); |
| 916 EXPECT_EQ(0u, *new_state_count); | 957 EXPECT_EQ(0u, *new_state_count); |
| 917 EXPECT_EQ(nullptr, new_state); | 958 EXPECT_EQ(nullptr, new_state); |
| 918 } | 959 } |
| 919 | 960 |
| 961 EXPECT_EQ(implicit_cast<mach_msg_trailer_type_t>(MACH_MSG_TRAILER_FORMAT_0), |
| 962 trailer->msgh_trailer_type); |
| 963 EXPECT_EQ(REQUESTED_TRAILER_SIZE(kMachMessageOptions), |
| 964 trailer->msgh_trailer_size); |
| 965 |
| 920 return ExcServerSuccessfulReturnValue(behavior, false); | 966 return ExcServerSuccessfulReturnValue(behavior, false); |
| 921 } | 967 } |
| 922 | 968 |
| 923 private: | 969 private: |
| 924 // MachMultiprocess: | 970 // MachMultiprocess: |
| 925 | 971 |
| 926 void MachMultiprocessParent() override { | 972 void MachMultiprocessParent() override { |
| 927 kern_return_t kr = | 973 kern_return_t kr = |
| 928 MachMessageServer::Run(this, | 974 MachMessageServer::Run(this, |
| 929 LocalPort(), | 975 LocalPort(), |
| 930 MACH_MSG_OPTION_NONE, | 976 kMachMessageOptions, |
| 931 MachMessageServer::kOneShot, | 977 MachMessageServer::kOneShot, |
| 932 MachMessageServer::kBlocking, | 978 MachMessageServer::kBlocking, |
| 933 MachMessageServer::kReceiveLargeError, | 979 MachMessageServer::kReceiveLargeError, |
| 934 0); | 980 0); |
| 935 EXPECT_EQ(KERN_SUCCESS, kr) | 981 EXPECT_EQ(KERN_SUCCESS, kr) |
| 936 << MachErrorMessage(kr, "MachMessageServer::Run"); | 982 << MachErrorMessage(kr, "MachMessageServer::Run"); |
| 937 | 983 |
| 938 EXPECT_TRUE(handled_); | 984 EXPECT_TRUE(handled_); |
| 939 } | 985 } |
| 940 | 986 |
| 941 void MachMultiprocessChild() override { | 987 void MachMultiprocessChild() override { |
| 942 // Set the parent as the exception handler for EXC_CRASH. | 988 // Set the parent as the exception handler for EXC_CRASH. |
| 943 kern_return_t kr = task_set_exception_ports( | 989 kern_return_t kr = task_set_exception_ports( |
| 944 mach_task_self(), EXC_MASK_CRASH, RemotePort(), behavior_, flavor_); | 990 mach_task_self(), EXC_MASK_CRASH, RemotePort(), behavior_, flavor_); |
| 945 ASSERT_EQ(KERN_SUCCESS, kr) | 991 ASSERT_EQ(KERN_SUCCESS, kr) |
| 946 << MachErrorMessage(kr, "task_set_exception_ports"); | 992 << MachErrorMessage(kr, "task_set_exception_ports"); |
| 947 | 993 |
| 948 // Now crash. | 994 // Now crash. |
| 949 __builtin_trap(); | 995 __builtin_trap(); |
| 950 } | 996 } |
| 951 | 997 |
| 952 exception_behavior_t behavior_; | 998 exception_behavior_t behavior_; |
| 953 thread_state_flavor_t flavor_; | 999 thread_state_flavor_t flavor_; |
| 954 mach_msg_type_number_t state_count_; | 1000 mach_msg_type_number_t state_count_; |
| 955 bool handled_; | 1001 bool handled_; |
| 956 | 1002 |
| 1003 static const mach_msg_option_t kMachMessageOptions = |
| 1004 MACH_RCV_TRAILER_TYPE(MACH_MSG_TRAILER_FORMAT_0); |
| 1005 |
| 957 DISALLOW_COPY_AND_ASSIGN(TestExcServerVariants); | 1006 DISALLOW_COPY_AND_ASSIGN(TestExcServerVariants); |
| 958 }; | 1007 }; |
| 959 | 1008 |
| 960 TEST(ExcServerVariants, ExceptionRaise) { | 1009 TEST(ExcServerVariants, ExceptionRaise) { |
| 961 TestExcServerVariants test_exc_server_variants( | 1010 TestExcServerVariants test_exc_server_variants( |
| 962 EXCEPTION_DEFAULT, THREAD_STATE_NONE, 0); | 1011 EXCEPTION_DEFAULT, THREAD_STATE_NONE, 0); |
| 963 test_exc_server_variants.Run(); | 1012 test_exc_server_variants.Run(); |
| 964 } | 1013 } |
| 965 | 1014 |
| 966 TEST(ExcServerVariants, ExceptionRaiseState) { | 1015 TEST(ExcServerVariants, ExceptionRaiseState) { |
| (...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1152 | 1201 |
| 1153 EXPECT_EQ(test_data.kr, | 1202 EXPECT_EQ(test_data.kr, |
| 1154 ExcServerSuccessfulReturnValue(test_data.behavior, | 1203 ExcServerSuccessfulReturnValue(test_data.behavior, |
| 1155 test_data.set_thread_state)); | 1204 test_data.set_thread_state)); |
| 1156 } | 1205 } |
| 1157 } | 1206 } |
| 1158 | 1207 |
| 1159 } // namespace | 1208 } // namespace |
| 1160 } // namespace test | 1209 } // namespace test |
| 1161 } // namespace crashpad | 1210 } // namespace crashpad |
| OLD | NEW |