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 |