OLD | NEW |
1 // Copyright 2014 The Crashpad Authors. All rights reserved. | 1 // Copyright 2014 The Crashpad Authors. All rights reserved. |
2 // | 2 // |
3 // Licensed under the Apache License, Version 2.0 (the "License"); | 3 // Licensed under the Apache License, Version 2.0 (the "License"); |
4 // you may not use this file except in compliance with the License. | 4 // you may not use this file except in compliance with the License. |
5 // You may obtain a copy of the License at | 5 // You may obtain a copy of the License at |
6 // | 6 // |
7 // http://www.apache.org/licenses/LICENSE-2.0 | 7 // http://www.apache.org/licenses/LICENSE-2.0 |
8 // | 8 // |
9 // Unless required by applicable law or agreed to in writing, software | 9 // Unless required by applicable law or agreed to in writing, software |
10 // distributed under the License is distributed on an "AS IS" BASIS, | 10 // distributed under the License is distributed on an "AS IS" BASIS, |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
70 } | 70 } |
71 | 71 |
72 // The definitions of the request and reply structures from mach_exc.h aren’t | 72 // The definitions of the request and reply structures from mach_exc.h aren’t |
73 // available here. They need custom initialization code, and the reply | 73 // available here. They need custom initialization code, and the reply |
74 // structures need verification code too, so duplicate the expected definitions | 74 // structures need verification code too, so duplicate the expected definitions |
75 // of the structures from both exc.h and mach_exc.h here in this file, and | 75 // 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 | 76 // provide the initialization and verification code as methods in true |
77 // object-oriented fashion. | 77 // object-oriented fashion. |
78 | 78 |
79 struct __attribute__((packed, aligned(4))) ExceptionRaiseRequest { | 79 struct __attribute__((packed, aligned(4))) ExceptionRaiseRequest { |
80 mach_msg_header_t Head; | 80 ExceptionRaiseRequest() { |
81 mach_msg_body_t msgh_body; | |
82 mach_msg_port_descriptor_t thread; | |
83 mach_msg_port_descriptor_t task; | |
84 NDR_record_t NDR; | |
85 exception_type_t exception; | |
86 mach_msg_type_number_t codeCnt; | |
87 integer_t code[2]; | |
88 | |
89 void InitializeForTesting() { | |
90 memset(this, 0xa5, sizeof(*this)); | 81 memset(this, 0xa5, sizeof(*this)); |
91 Head.msgh_bits = | 82 Head.msgh_bits = |
92 MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND_ONCE, MACH_MSG_TYPE_PORT_SEND) | | 83 MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND_ONCE, MACH_MSG_TYPE_PORT_SEND) | |
93 MACH_MSGH_BITS_COMPLEX; | 84 MACH_MSGH_BITS_COMPLEX; |
94 Head.msgh_size = sizeof(*this); | 85 Head.msgh_size = sizeof(*this); |
95 Head.msgh_remote_port = kClientRemotePort; | 86 Head.msgh_remote_port = kClientRemotePort; |
96 Head.msgh_local_port = kServerLocalPort; | 87 Head.msgh_local_port = kServerLocalPort; |
97 Head.msgh_id = 2401; | 88 Head.msgh_id = 2401; |
98 msgh_body.msgh_descriptor_count = 2; | 89 msgh_body.msgh_descriptor_count = 2; |
99 InitializeMachMsgPortDescriptor(&thread, kExceptionThreadPort); | 90 InitializeMachMsgPortDescriptor(&thread, kExceptionThreadPort); |
100 InitializeMachMsgPortDescriptor(&task, kExceptionTaskPort); | 91 InitializeMachMsgPortDescriptor(&task, kExceptionTaskPort); |
101 NDR = NDR_record; | 92 NDR = NDR_record; |
102 exception = kExceptionType; | 93 exception = kExceptionType; |
103 codeCnt = 2; | 94 codeCnt = 2; |
104 code[0] = kTestExceptonCodes[0]; | 95 code[0] = kTestExceptonCodes[0]; |
105 code[1] = kTestExceptonCodes[1]; | 96 code[1] = kTestExceptonCodes[1]; |
106 } | 97 } |
| 98 |
| 99 mach_msg_header_t Head; |
| 100 mach_msg_body_t msgh_body; |
| 101 mach_msg_port_descriptor_t thread; |
| 102 mach_msg_port_descriptor_t task; |
| 103 NDR_record_t NDR; |
| 104 exception_type_t exception; |
| 105 mach_msg_type_number_t codeCnt; |
| 106 integer_t code[2]; |
107 }; | 107 }; |
108 | 108 |
109 struct __attribute__((packed, aligned(4))) ExceptionRaiseReply { | 109 struct __attribute__((packed, aligned(4))) ExceptionRaiseReply { |
110 mach_msg_header_t Head; | 110 ExceptionRaiseReply() { |
111 NDR_record_t NDR; | |
112 kern_return_t RetCode; | |
113 | |
114 void InitializeForTesting() { | |
115 memset(this, 0x5a, sizeof(*this)); | 111 memset(this, 0x5a, sizeof(*this)); |
116 RetCode = KERN_FAILURE; | 112 RetCode = KERN_FAILURE; |
117 } | 113 } |
118 | 114 |
119 // Verify accepts a |behavior| parameter because the same message format and | 115 // Verify accepts a |behavior| parameter because the same message format and |
120 // verification function is used for ExceptionRaiseReply and | 116 // verification function is used for ExceptionRaiseReply and |
121 // MachExceptionRaiseReply. Knowing which behavior is expected allows the | 117 // MachExceptionRaiseReply. Knowing which behavior is expected allows the |
122 // message ID to be checked. | 118 // message ID to be checked. |
123 void Verify(exception_behavior_t behavior) { | 119 void Verify(exception_behavior_t behavior) { |
124 EXPECT_EQ(implicit_cast<mach_msg_bits_t>( | 120 EXPECT_EQ(implicit_cast<mach_msg_bits_t>( |
(...skipping 10 matching lines...) Expand all Loading... |
135 EXPECT_EQ(2505, Head.msgh_id); | 131 EXPECT_EQ(2505, Head.msgh_id); |
136 break; | 132 break; |
137 default: | 133 default: |
138 ADD_FAILURE() << "behavior " << behavior << ", Head.msgh_id " | 134 ADD_FAILURE() << "behavior " << behavior << ", Head.msgh_id " |
139 << Head.msgh_id; | 135 << Head.msgh_id; |
140 break; | 136 break; |
141 } | 137 } |
142 EXPECT_EQ(0, memcmp(&NDR, &NDR_record, sizeof(NDR))); | 138 EXPECT_EQ(0, memcmp(&NDR, &NDR_record, sizeof(NDR))); |
143 EXPECT_EQ(KERN_SUCCESS, RetCode); | 139 EXPECT_EQ(KERN_SUCCESS, RetCode); |
144 } | 140 } |
| 141 |
| 142 mach_msg_header_t Head; |
| 143 NDR_record_t NDR; |
| 144 kern_return_t RetCode; |
145 }; | 145 }; |
146 | 146 |
147 struct __attribute__((packed, aligned(4))) ExceptionRaiseStateRequest { | 147 struct __attribute__((packed, aligned(4))) ExceptionRaiseStateRequest { |
148 mach_msg_header_t Head; | 148 ExceptionRaiseStateRequest() { |
149 NDR_record_t NDR; | |
150 exception_type_t exception; | |
151 mach_msg_type_number_t codeCnt; | |
152 integer_t code[2]; | |
153 int flavor; | |
154 mach_msg_type_number_t old_stateCnt; | |
155 natural_t old_state[THREAD_STATE_MAX]; | |
156 | |
157 void InitializeForTesting() { | |
158 memset(this, 0xa5, sizeof(*this)); | 149 memset(this, 0xa5, sizeof(*this)); |
159 Head.msgh_bits = | 150 Head.msgh_bits = |
160 MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND_ONCE, MACH_MSG_TYPE_PORT_SEND); | 151 MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND_ONCE, MACH_MSG_TYPE_PORT_SEND); |
161 Head.msgh_size = sizeof(*this); | 152 Head.msgh_size = sizeof(*this); |
162 Head.msgh_remote_port = kClientRemotePort; | 153 Head.msgh_remote_port = kClientRemotePort; |
163 Head.msgh_local_port = kServerLocalPort; | 154 Head.msgh_local_port = kServerLocalPort; |
164 Head.msgh_id = 2402; | 155 Head.msgh_id = 2402; |
165 NDR = NDR_record; | 156 NDR = NDR_record; |
166 exception = kExceptionType; | 157 exception = kExceptionType; |
167 codeCnt = 2; | 158 codeCnt = 2; |
168 code[0] = kTestExceptonCodes[0]; | 159 code[0] = kTestExceptonCodes[0]; |
169 code[1] = kTestExceptonCodes[1]; | 160 code[1] = kTestExceptonCodes[1]; |
170 flavor = kThreadStateFlavor; | 161 flavor = kThreadStateFlavor; |
171 old_stateCnt = kThreadStateFlavorCount; | 162 old_stateCnt = kThreadStateFlavorCount; |
172 | 163 |
173 // Adjust the message size for the data that it’s actually carrying, which | 164 // Adjust the message size for the data that it’s actually carrying, which |
174 // may be smaller than the maximum that it can carry. | 165 // may be smaller than the maximum that it can carry. |
175 Head.msgh_size += sizeof(old_state[0]) * old_stateCnt - sizeof(old_state); | 166 Head.msgh_size += sizeof(old_state[0]) * old_stateCnt - sizeof(old_state); |
176 } | 167 } |
| 168 |
| 169 mach_msg_header_t Head; |
| 170 NDR_record_t NDR; |
| 171 exception_type_t exception; |
| 172 mach_msg_type_number_t codeCnt; |
| 173 integer_t code[2]; |
| 174 int flavor; |
| 175 mach_msg_type_number_t old_stateCnt; |
| 176 natural_t old_state[THREAD_STATE_MAX]; |
177 }; | 177 }; |
178 | 178 |
179 struct __attribute__((packed, aligned(4))) ExceptionRaiseStateReply { | 179 struct __attribute__((packed, aligned(4))) ExceptionRaiseStateReply { |
180 mach_msg_header_t Head; | 180 ExceptionRaiseStateReply() { |
181 NDR_record_t NDR; | |
182 kern_return_t RetCode; | |
183 int flavor; | |
184 mach_msg_type_number_t new_stateCnt; | |
185 natural_t new_state[THREAD_STATE_MAX]; | |
186 | |
187 void InitializeForTesting() { | |
188 memset(this, 0x5a, sizeof(*this)); | 181 memset(this, 0x5a, sizeof(*this)); |
189 RetCode = KERN_FAILURE; | 182 RetCode = KERN_FAILURE; |
190 } | 183 } |
191 | 184 |
192 // Verify accepts a |behavior| parameter because the same message format and | 185 // Verify accepts a |behavior| parameter because the same message format and |
193 // verification function is used for ExceptionRaiseStateReply, | 186 // verification function is used for ExceptionRaiseStateReply, |
194 // ExceptionRaiseStateIdentityReply, MachExceptionRaiseStateReply, and | 187 // ExceptionRaiseStateIdentityReply, MachExceptionRaiseStateReply, and |
195 // MachExceptionRaiseStateIdentityReply. Knowing which behavior is expected | 188 // MachExceptionRaiseStateIdentityReply. Knowing which behavior is expected |
196 // allows the message ID to be checked. | 189 // allows the message ID to be checked. |
197 void Verify(exception_behavior_t behavior) { | 190 void Verify(exception_behavior_t behavior) { |
(...skipping 19 matching lines...) Expand all Loading... |
217 default: | 210 default: |
218 ADD_FAILURE() << "behavior " << behavior << ", Head.msgh_id " | 211 ADD_FAILURE() << "behavior " << behavior << ", Head.msgh_id " |
219 << Head.msgh_id; | 212 << Head.msgh_id; |
220 break; | 213 break; |
221 } | 214 } |
222 EXPECT_EQ(0, memcmp(&NDR, &NDR_record, sizeof(NDR))); | 215 EXPECT_EQ(0, memcmp(&NDR, &NDR_record, sizeof(NDR))); |
223 EXPECT_EQ(KERN_SUCCESS, RetCode); | 216 EXPECT_EQ(KERN_SUCCESS, RetCode); |
224 EXPECT_EQ(kThreadStateFlavor, flavor); | 217 EXPECT_EQ(kThreadStateFlavor, flavor); |
225 EXPECT_EQ(arraysize(new_state), new_stateCnt); | 218 EXPECT_EQ(arraysize(new_state), new_stateCnt); |
226 } | 219 } |
| 220 |
| 221 mach_msg_header_t Head; |
| 222 NDR_record_t NDR; |
| 223 kern_return_t RetCode; |
| 224 int flavor; |
| 225 mach_msg_type_number_t new_stateCnt; |
| 226 natural_t new_state[THREAD_STATE_MAX]; |
227 }; | 227 }; |
228 | 228 |
229 struct __attribute__((packed, aligned(4))) ExceptionRaiseStateIdentityRequest { | 229 struct __attribute__((packed, aligned(4))) ExceptionRaiseStateIdentityRequest { |
230 mach_msg_header_t Head; | 230 ExceptionRaiseStateIdentityRequest() { |
231 mach_msg_body_t msgh_body; | |
232 mach_msg_port_descriptor_t thread; | |
233 mach_msg_port_descriptor_t task; | |
234 NDR_record_t NDR; | |
235 exception_type_t exception; | |
236 mach_msg_type_number_t codeCnt; | |
237 integer_t code[2]; | |
238 int flavor; | |
239 mach_msg_type_number_t old_stateCnt; | |
240 natural_t old_state[THREAD_STATE_MAX]; | |
241 | |
242 void InitializeForTesting() { | |
243 memset(this, 0xa5, sizeof(*this)); | 231 memset(this, 0xa5, sizeof(*this)); |
244 Head.msgh_bits = | 232 Head.msgh_bits = |
245 MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND_ONCE, MACH_MSG_TYPE_PORT_SEND) | | 233 MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND_ONCE, MACH_MSG_TYPE_PORT_SEND) | |
246 MACH_MSGH_BITS_COMPLEX; | 234 MACH_MSGH_BITS_COMPLEX; |
247 Head.msgh_size = sizeof(*this); | 235 Head.msgh_size = sizeof(*this); |
248 Head.msgh_remote_port = kClientRemotePort; | 236 Head.msgh_remote_port = kClientRemotePort; |
249 Head.msgh_local_port = kServerLocalPort; | 237 Head.msgh_local_port = kServerLocalPort; |
250 Head.msgh_id = 2403; | 238 Head.msgh_id = 2403; |
251 msgh_body.msgh_descriptor_count = 2; | 239 msgh_body.msgh_descriptor_count = 2; |
252 InitializeMachMsgPortDescriptor(&thread, kExceptionThreadPort); | 240 InitializeMachMsgPortDescriptor(&thread, kExceptionThreadPort); |
253 InitializeMachMsgPortDescriptor(&task, kExceptionTaskPort); | 241 InitializeMachMsgPortDescriptor(&task, kExceptionTaskPort); |
254 NDR = NDR_record; | 242 NDR = NDR_record; |
255 exception = kExceptionType; | 243 exception = kExceptionType; |
256 codeCnt = 2; | 244 codeCnt = 2; |
257 code[0] = kTestExceptonCodes[0]; | 245 code[0] = kTestExceptonCodes[0]; |
258 code[1] = kTestExceptonCodes[1]; | 246 code[1] = kTestExceptonCodes[1]; |
259 flavor = kThreadStateFlavor; | 247 flavor = kThreadStateFlavor; |
260 old_stateCnt = kThreadStateFlavorCount; | 248 old_stateCnt = kThreadStateFlavorCount; |
261 | 249 |
262 // Adjust the message size for the data that it’s actually carrying, which | 250 // Adjust the message size for the data that it’s actually carrying, which |
263 // may be smaller than the maximum that it can carry. | 251 // may be smaller than the maximum that it can carry. |
264 Head.msgh_size += sizeof(old_state[0]) * old_stateCnt - sizeof(old_state); | 252 Head.msgh_size += sizeof(old_state[0]) * old_stateCnt - sizeof(old_state); |
265 } | 253 } |
266 }; | |
267 | 254 |
268 // The reply messages for exception_raise_state and | |
269 // exception_raise_state_identity are identical. | |
270 using ExceptionRaiseStateIdentityReply = ExceptionRaiseStateReply; | |
271 | |
272 struct __attribute__((packed, aligned(4))) MachExceptionRaiseRequest { | |
273 mach_msg_header_t Head; | 255 mach_msg_header_t Head; |
274 mach_msg_body_t msgh_body; | 256 mach_msg_body_t msgh_body; |
275 mach_msg_port_descriptor_t thread; | 257 mach_msg_port_descriptor_t thread; |
276 mach_msg_port_descriptor_t task; | 258 mach_msg_port_descriptor_t task; |
277 NDR_record_t NDR; | 259 NDR_record_t NDR; |
278 exception_type_t exception; | 260 exception_type_t exception; |
279 mach_msg_type_number_t codeCnt; | 261 mach_msg_type_number_t codeCnt; |
280 int64_t code[2]; | 262 integer_t code[2]; |
| 263 int flavor; |
| 264 mach_msg_type_number_t old_stateCnt; |
| 265 natural_t old_state[THREAD_STATE_MAX]; |
| 266 }; |
281 | 267 |
282 void InitializeForTesting() { | 268 // The reply messages for exception_raise_state and |
| 269 // exception_raise_state_identity are identical. |
| 270 using ExceptionRaiseStateIdentityReply = ExceptionRaiseStateReply; |
| 271 |
| 272 struct __attribute__((packed, aligned(4))) MachExceptionRaiseRequest { |
| 273 MachExceptionRaiseRequest() { |
283 memset(this, 0xa5, sizeof(*this)); | 274 memset(this, 0xa5, sizeof(*this)); |
284 Head.msgh_bits = | 275 Head.msgh_bits = |
285 MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND_ONCE, MACH_MSG_TYPE_PORT_SEND) | | 276 MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND_ONCE, MACH_MSG_TYPE_PORT_SEND) | |
286 MACH_MSGH_BITS_COMPLEX; | 277 MACH_MSGH_BITS_COMPLEX; |
287 Head.msgh_size = sizeof(*this); | 278 Head.msgh_size = sizeof(*this); |
288 Head.msgh_remote_port = kClientRemotePort; | 279 Head.msgh_remote_port = kClientRemotePort; |
289 Head.msgh_local_port = kServerLocalPort; | 280 Head.msgh_local_port = kServerLocalPort; |
290 Head.msgh_id = 2405; | 281 Head.msgh_id = 2405; |
291 msgh_body.msgh_descriptor_count = 2; | 282 msgh_body.msgh_descriptor_count = 2; |
292 InitializeMachMsgPortDescriptor(&thread, kExceptionThreadPort); | 283 InitializeMachMsgPortDescriptor(&thread, kExceptionThreadPort); |
293 InitializeMachMsgPortDescriptor(&task, kExceptionTaskPort); | 284 InitializeMachMsgPortDescriptor(&task, kExceptionTaskPort); |
294 NDR = NDR_record; | 285 NDR = NDR_record; |
295 exception = kExceptionType; | 286 exception = kExceptionType; |
296 codeCnt = 2; | 287 codeCnt = 2; |
297 code[0] = kTestMachExceptionCodes[0]; | 288 code[0] = kTestMachExceptionCodes[0]; |
298 code[1] = kTestMachExceptionCodes[1]; | 289 code[1] = kTestMachExceptionCodes[1]; |
299 } | 290 } |
| 291 |
| 292 mach_msg_header_t Head; |
| 293 mach_msg_body_t msgh_body; |
| 294 mach_msg_port_descriptor_t thread; |
| 295 mach_msg_port_descriptor_t task; |
| 296 NDR_record_t NDR; |
| 297 exception_type_t exception; |
| 298 mach_msg_type_number_t codeCnt; |
| 299 int64_t code[2]; |
300 }; | 300 }; |
301 | 301 |
302 // The reply messages for exception_raise and mach_exception_raise are | 302 // The reply messages for exception_raise and mach_exception_raise are |
303 // identical. | 303 // identical. |
304 using MachExceptionRaiseReply = ExceptionRaiseReply; | 304 using MachExceptionRaiseReply = ExceptionRaiseReply; |
305 | 305 |
306 struct __attribute__((packed, aligned(4))) MachExceptionRaiseStateRequest { | 306 struct __attribute__((packed, aligned(4))) MachExceptionRaiseStateRequest { |
307 mach_msg_header_t Head; | 307 MachExceptionRaiseStateRequest() { |
308 NDR_record_t NDR; | |
309 exception_type_t exception; | |
310 mach_msg_type_number_t codeCnt; | |
311 int64_t code[2]; | |
312 int flavor; | |
313 mach_msg_type_number_t old_stateCnt; | |
314 natural_t old_state[THREAD_STATE_MAX]; | |
315 | |
316 void InitializeForTesting() { | |
317 memset(this, 0xa5, sizeof(*this)); | 308 memset(this, 0xa5, sizeof(*this)); |
318 Head.msgh_bits = | 309 Head.msgh_bits = |
319 MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND_ONCE, MACH_MSG_TYPE_PORT_SEND); | 310 MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND_ONCE, MACH_MSG_TYPE_PORT_SEND); |
320 Head.msgh_size = sizeof(*this); | 311 Head.msgh_size = sizeof(*this); |
321 Head.msgh_remote_port = kClientRemotePort; | 312 Head.msgh_remote_port = kClientRemotePort; |
322 Head.msgh_local_port = kServerLocalPort; | 313 Head.msgh_local_port = kServerLocalPort; |
323 Head.msgh_id = 2406; | 314 Head.msgh_id = 2406; |
324 NDR = NDR_record; | 315 NDR = NDR_record; |
325 exception = kExceptionType; | 316 exception = kExceptionType; |
326 codeCnt = 2; | 317 codeCnt = 2; |
327 code[0] = kTestMachExceptionCodes[0]; | 318 code[0] = kTestMachExceptionCodes[0]; |
328 code[1] = kTestMachExceptionCodes[1]; | 319 code[1] = kTestMachExceptionCodes[1]; |
329 flavor = kThreadStateFlavor; | 320 flavor = kThreadStateFlavor; |
330 old_stateCnt = kThreadStateFlavorCount; | 321 old_stateCnt = kThreadStateFlavorCount; |
331 | 322 |
332 // Adjust the message size for the data that it’s actually carrying, which | 323 // Adjust the message size for the data that it’s actually carrying, which |
333 // may be smaller than the maximum that it can carry. | 324 // may be smaller than the maximum that it can carry. |
334 Head.msgh_size += sizeof(old_state[0]) * old_stateCnt - sizeof(old_state); | 325 Head.msgh_size += sizeof(old_state[0]) * old_stateCnt - sizeof(old_state); |
335 } | 326 } |
336 }; | |
337 | 327 |
338 // The reply messages for exception_raise_state and mach_exception_raise_state | |
339 // are identical. | |
340 using MachExceptionRaiseStateReply = ExceptionRaiseStateReply; | |
341 | |
342 struct __attribute__((packed, | |
343 aligned(4))) MachExceptionRaiseStateIdentityRequest { | |
344 mach_msg_header_t Head; | 328 mach_msg_header_t Head; |
345 mach_msg_body_t msgh_body; | |
346 mach_msg_port_descriptor_t thread; | |
347 mach_msg_port_descriptor_t task; | |
348 NDR_record_t NDR; | 329 NDR_record_t NDR; |
349 exception_type_t exception; | 330 exception_type_t exception; |
350 mach_msg_type_number_t codeCnt; | 331 mach_msg_type_number_t codeCnt; |
351 int64_t code[2]; | 332 int64_t code[2]; |
352 int flavor; | 333 int flavor; |
353 mach_msg_type_number_t old_stateCnt; | 334 mach_msg_type_number_t old_stateCnt; |
354 natural_t old_state[THREAD_STATE_MAX]; | 335 natural_t old_state[THREAD_STATE_MAX]; |
| 336 }; |
355 | 337 |
356 void InitializeForTesting() { | 338 // The reply messages for exception_raise_state and mach_exception_raise_state |
| 339 // are identical. |
| 340 using MachExceptionRaiseStateReply = ExceptionRaiseStateReply; |
| 341 |
| 342 struct __attribute__((packed, |
| 343 aligned(4))) MachExceptionRaiseStateIdentityRequest { |
| 344 MachExceptionRaiseStateIdentityRequest() { |
357 memset(this, 0xa5, sizeof(*this)); | 345 memset(this, 0xa5, sizeof(*this)); |
358 Head.msgh_bits = | 346 Head.msgh_bits = |
359 MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND_ONCE, MACH_MSG_TYPE_PORT_SEND) | | 347 MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND_ONCE, MACH_MSG_TYPE_PORT_SEND) | |
360 MACH_MSGH_BITS_COMPLEX; | 348 MACH_MSGH_BITS_COMPLEX; |
361 Head.msgh_size = sizeof(*this); | 349 Head.msgh_size = sizeof(*this); |
362 Head.msgh_remote_port = kClientRemotePort; | 350 Head.msgh_remote_port = kClientRemotePort; |
363 Head.msgh_local_port = kServerLocalPort; | 351 Head.msgh_local_port = kServerLocalPort; |
364 Head.msgh_id = 2407; | 352 Head.msgh_id = 2407; |
365 msgh_body.msgh_descriptor_count = 2; | 353 msgh_body.msgh_descriptor_count = 2; |
366 InitializeMachMsgPortDescriptor(&thread, kExceptionThreadPort); | 354 InitializeMachMsgPortDescriptor(&thread, kExceptionThreadPort); |
367 InitializeMachMsgPortDescriptor(&task, kExceptionTaskPort); | 355 InitializeMachMsgPortDescriptor(&task, kExceptionTaskPort); |
368 NDR = NDR_record; | 356 NDR = NDR_record; |
369 exception = kExceptionType; | 357 exception = kExceptionType; |
370 codeCnt = 2; | 358 codeCnt = 2; |
371 code[0] = kTestMachExceptionCodes[0]; | 359 code[0] = kTestMachExceptionCodes[0]; |
372 code[1] = kTestMachExceptionCodes[1]; | 360 code[1] = kTestMachExceptionCodes[1]; |
373 flavor = kThreadStateFlavor; | 361 flavor = kThreadStateFlavor; |
374 old_stateCnt = kThreadStateFlavorCount; | 362 old_stateCnt = kThreadStateFlavorCount; |
375 | 363 |
376 // Adjust the message size for the data that it’s actually carrying, which | 364 // Adjust the message size for the data that it’s actually carrying, which |
377 // may be smaller than the maximum that it can carry. | 365 // may be smaller than the maximum that it can carry. |
378 Head.msgh_size += sizeof(old_state[0]) * old_stateCnt - sizeof(old_state); | 366 Head.msgh_size += sizeof(old_state[0]) * old_stateCnt - sizeof(old_state); |
379 } | 367 } |
| 368 |
| 369 mach_msg_header_t Head; |
| 370 mach_msg_body_t msgh_body; |
| 371 mach_msg_port_descriptor_t thread; |
| 372 mach_msg_port_descriptor_t task; |
| 373 NDR_record_t NDR; |
| 374 exception_type_t exception; |
| 375 mach_msg_type_number_t codeCnt; |
| 376 int64_t code[2]; |
| 377 int flavor; |
| 378 mach_msg_type_number_t old_stateCnt; |
| 379 natural_t old_state[THREAD_STATE_MAX]; |
380 }; | 380 }; |
381 | 381 |
382 // The reply messages for exception_raise_state_identity and | 382 // The reply messages for exception_raise_state_identity and |
383 // mach_exception_raise_state_identity are identical. | 383 // mach_exception_raise_state_identity are identical. |
384 using MachExceptionRaiseStateIdentityReply = ExceptionRaiseStateIdentityReply; | 384 using MachExceptionRaiseStateIdentityReply = ExceptionRaiseStateIdentityReply; |
385 | 385 |
386 // InvalidRequest and BadIDErrorReply are used to test that | 386 // InvalidRequest and BadIDErrorReply are used to test that |
387 // UniversalMachExcServer deals appropriately with messages that it does not | 387 // UniversalMachExcServer deals appropriately with messages that it does not |
388 // understand: messages with an unknown Head.msgh_id. | 388 // understand: messages with an unknown Head.msgh_id. |
389 | 389 |
390 struct __attribute__((packed, aligned(4))) InvalidRequest | 390 struct InvalidRequest : public mach_msg_empty_send_t { |
391 : public mach_msg_empty_send_t { | 391 explicit InvalidRequest(mach_msg_id_t id) { |
392 void InitializeForTesting(mach_msg_id_t id) { | |
393 memset(this, 0xa5, sizeof(*this)); | 392 memset(this, 0xa5, sizeof(*this)); |
394 header.msgh_bits = | 393 header.msgh_bits = |
395 MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND_ONCE, MACH_MSG_TYPE_PORT_SEND); | 394 MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND_ONCE, MACH_MSG_TYPE_PORT_SEND); |
396 header.msgh_size = sizeof(*this); | 395 header.msgh_size = sizeof(*this); |
397 header.msgh_remote_port = kClientRemotePort; | 396 header.msgh_remote_port = kClientRemotePort; |
398 header.msgh_local_port = kServerLocalPort; | 397 header.msgh_local_port = kServerLocalPort; |
399 header.msgh_id = id; | 398 header.msgh_id = id; |
400 } | 399 } |
401 }; | 400 }; |
402 | 401 |
403 struct __attribute__((packed, aligned(4))) BadIDErrorReply | 402 struct BadIDErrorReply : public mig_reply_error_t { |
404 : public mig_reply_error_t { | 403 BadIDErrorReply() { |
405 void InitializeForTesting() { | |
406 memset(this, 0x5a, sizeof(*this)); | 404 memset(this, 0x5a, sizeof(*this)); |
407 RetCode = KERN_FAILURE; | 405 RetCode = KERN_FAILURE; |
408 } | 406 } |
409 | 407 |
410 void Verify(mach_msg_id_t id) { | 408 void Verify(mach_msg_id_t id) { |
411 EXPECT_EQ(implicit_cast<mach_msg_bits_t>( | 409 EXPECT_EQ(implicit_cast<mach_msg_bits_t>( |
412 MACH_MSGH_BITS(MACH_MSG_TYPE_MOVE_SEND_ONCE, 0)), | 410 MACH_MSGH_BITS(MACH_MSG_TYPE_MOVE_SEND_ONCE, 0)), |
413 Head.msgh_bits); | 411 Head.msgh_bits); |
414 EXPECT_EQ(sizeof(*this), Head.msgh_size); | 412 EXPECT_EQ(sizeof(*this), Head.msgh_size); |
415 EXPECT_EQ(kClientRemotePort, Head.msgh_remote_port); | 413 EXPECT_EQ(kClientRemotePort, Head.msgh_remote_port); |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
544 ~ScopedDefaultValue() { DefaultValue<T>::Clear(); } | 542 ~ScopedDefaultValue() { DefaultValue<T>::Clear(); } |
545 }; | 543 }; |
546 | 544 |
547 TEST(ExcServerVariants, MockExceptionRaise) { | 545 TEST(ExcServerVariants, MockExceptionRaise) { |
548 ScopedDefaultValue<kern_return_t> default_kern_return_t(KERN_FAILURE); | 546 ScopedDefaultValue<kern_return_t> default_kern_return_t(KERN_FAILURE); |
549 | 547 |
550 MockUniversalMachExcServer server; | 548 MockUniversalMachExcServer server; |
551 | 549 |
552 ExceptionRaiseRequest request; | 550 ExceptionRaiseRequest request; |
553 EXPECT_LE(sizeof(request), server.MachMessageServerRequestSize()); | 551 EXPECT_LE(sizeof(request), server.MachMessageServerRequestSize()); |
554 request.InitializeForTesting(); | |
555 | 552 |
556 ExceptionRaiseReply reply; | 553 ExceptionRaiseReply reply; |
557 EXPECT_LE(sizeof(reply), server.MachMessageServerReplySize()); | 554 EXPECT_LE(sizeof(reply), server.MachMessageServerReplySize()); |
558 reply.InitializeForTesting(); | |
559 | 555 |
560 const exception_behavior_t kExceptionBehavior = EXCEPTION_DEFAULT; | 556 const exception_behavior_t kExceptionBehavior = EXCEPTION_DEFAULT; |
561 | 557 |
562 EXPECT_CALL(server, | 558 EXPECT_CALL(server, |
563 MockCatchMachException(kExceptionBehavior, | 559 MockCatchMachException(kExceptionBehavior, |
564 kServerLocalPort, | 560 kServerLocalPort, |
565 kExceptionThreadPort, | 561 kExceptionThreadPort, |
566 kExceptionTaskPort, | 562 kExceptionTaskPort, |
567 kExceptionType, | 563 kExceptionType, |
568 AreExceptionCodes(kTestExceptonCodes[0], | 564 AreExceptionCodes(kTestExceptonCodes[0], |
(...skipping 14 matching lines...) Expand all Loading... |
583 reply.Verify(kExceptionBehavior); | 579 reply.Verify(kExceptionBehavior); |
584 } | 580 } |
585 | 581 |
586 TEST(ExcServerVariants, MockExceptionRaiseState) { | 582 TEST(ExcServerVariants, MockExceptionRaiseState) { |
587 ScopedDefaultValue<kern_return_t> default_kern_return_t(KERN_FAILURE); | 583 ScopedDefaultValue<kern_return_t> default_kern_return_t(KERN_FAILURE); |
588 | 584 |
589 MockUniversalMachExcServer server; | 585 MockUniversalMachExcServer server; |
590 | 586 |
591 ExceptionRaiseStateRequest request; | 587 ExceptionRaiseStateRequest request; |
592 EXPECT_LE(sizeof(request), server.MachMessageServerRequestSize()); | 588 EXPECT_LE(sizeof(request), server.MachMessageServerRequestSize()); |
593 request.InitializeForTesting(); | |
594 | 589 |
595 ExceptionRaiseStateReply reply; | 590 ExceptionRaiseStateReply reply; |
596 EXPECT_LE(sizeof(reply), server.MachMessageServerReplySize()); | 591 EXPECT_LE(sizeof(reply), server.MachMessageServerReplySize()); |
597 reply.InitializeForTesting(); | |
598 | 592 |
599 const exception_behavior_t kExceptionBehavior = EXCEPTION_STATE; | 593 const exception_behavior_t kExceptionBehavior = EXCEPTION_STATE; |
600 | 594 |
601 EXPECT_CALL( | 595 EXPECT_CALL( |
602 server, | 596 server, |
603 MockCatchMachException( | 597 MockCatchMachException( |
604 kExceptionBehavior, | 598 kExceptionBehavior, |
605 kServerLocalPort, | 599 kServerLocalPort, |
606 THREAD_NULL, | 600 THREAD_NULL, |
607 TASK_NULL, | 601 TASK_NULL, |
(...skipping 18 matching lines...) Expand all Loading... |
626 reply.Verify(kExceptionBehavior); | 620 reply.Verify(kExceptionBehavior); |
627 } | 621 } |
628 | 622 |
629 TEST(ExcServerVariants, MockExceptionRaiseStateIdentity) { | 623 TEST(ExcServerVariants, MockExceptionRaiseStateIdentity) { |
630 ScopedDefaultValue<kern_return_t> default_kern_return_t(KERN_FAILURE); | 624 ScopedDefaultValue<kern_return_t> default_kern_return_t(KERN_FAILURE); |
631 | 625 |
632 MockUniversalMachExcServer server; | 626 MockUniversalMachExcServer server; |
633 | 627 |
634 ExceptionRaiseStateIdentityRequest request; | 628 ExceptionRaiseStateIdentityRequest request; |
635 EXPECT_LE(sizeof(request), server.MachMessageServerRequestSize()); | 629 EXPECT_LE(sizeof(request), server.MachMessageServerRequestSize()); |
636 request.InitializeForTesting(); | |
637 | 630 |
638 ExceptionRaiseStateIdentityReply reply; | 631 ExceptionRaiseStateIdentityReply reply; |
639 EXPECT_LE(sizeof(reply), server.MachMessageServerReplySize()); | 632 EXPECT_LE(sizeof(reply), server.MachMessageServerReplySize()); |
640 reply.InitializeForTesting(); | |
641 | 633 |
642 const exception_behavior_t kExceptionBehavior = EXCEPTION_STATE_IDENTITY; | 634 const exception_behavior_t kExceptionBehavior = EXCEPTION_STATE_IDENTITY; |
643 | 635 |
644 EXPECT_CALL( | 636 EXPECT_CALL( |
645 server, | 637 server, |
646 MockCatchMachException( | 638 MockCatchMachException( |
647 kExceptionBehavior, | 639 kExceptionBehavior, |
648 kServerLocalPort, | 640 kServerLocalPort, |
649 kExceptionThreadPort, | 641 kExceptionThreadPort, |
650 kExceptionTaskPort, | 642 kExceptionTaskPort, |
(...skipping 15 matching lines...) Expand all Loading... |
666 reply.Verify(kExceptionBehavior); | 658 reply.Verify(kExceptionBehavior); |
667 } | 659 } |
668 | 660 |
669 TEST(ExcServerVariants, MockMachExceptionRaise) { | 661 TEST(ExcServerVariants, MockMachExceptionRaise) { |
670 ScopedDefaultValue<kern_return_t> default_kern_return_t(KERN_FAILURE); | 662 ScopedDefaultValue<kern_return_t> default_kern_return_t(KERN_FAILURE); |
671 | 663 |
672 MockUniversalMachExcServer server; | 664 MockUniversalMachExcServer server; |
673 | 665 |
674 MachExceptionRaiseRequest request; | 666 MachExceptionRaiseRequest request; |
675 EXPECT_LE(sizeof(request), server.MachMessageServerRequestSize()); | 667 EXPECT_LE(sizeof(request), server.MachMessageServerRequestSize()); |
676 request.InitializeForTesting(); | |
677 | 668 |
678 MachExceptionRaiseReply reply; | 669 MachExceptionRaiseReply reply; |
679 EXPECT_LE(sizeof(reply), server.MachMessageServerReplySize()); | 670 EXPECT_LE(sizeof(reply), server.MachMessageServerReplySize()); |
680 reply.InitializeForTesting(); | |
681 | 671 |
682 const exception_behavior_t kExceptionBehavior = | 672 const exception_behavior_t kExceptionBehavior = |
683 EXCEPTION_DEFAULT | MACH_EXCEPTION_CODES; | 673 EXCEPTION_DEFAULT | MACH_EXCEPTION_CODES; |
684 | 674 |
685 EXPECT_CALL( | 675 EXPECT_CALL( |
686 server, | 676 server, |
687 MockCatchMachException(kExceptionBehavior, | 677 MockCatchMachException(kExceptionBehavior, |
688 kServerLocalPort, | 678 kServerLocalPort, |
689 kExceptionThreadPort, | 679 kExceptionThreadPort, |
690 kExceptionTaskPort, | 680 kExceptionTaskPort, |
(...skipping 16 matching lines...) Expand all Loading... |
707 reply.Verify(kExceptionBehavior); | 697 reply.Verify(kExceptionBehavior); |
708 } | 698 } |
709 | 699 |
710 TEST(ExcServerVariants, MockMachExceptionRaiseState) { | 700 TEST(ExcServerVariants, MockMachExceptionRaiseState) { |
711 ScopedDefaultValue<kern_return_t> default_kern_return_t(KERN_FAILURE); | 701 ScopedDefaultValue<kern_return_t> default_kern_return_t(KERN_FAILURE); |
712 | 702 |
713 MockUniversalMachExcServer server; | 703 MockUniversalMachExcServer server; |
714 | 704 |
715 MachExceptionRaiseStateRequest request; | 705 MachExceptionRaiseStateRequest request; |
716 EXPECT_LE(sizeof(request), server.MachMessageServerRequestSize()); | 706 EXPECT_LE(sizeof(request), server.MachMessageServerRequestSize()); |
717 request.InitializeForTesting(); | |
718 | 707 |
719 MachExceptionRaiseStateReply reply; | 708 MachExceptionRaiseStateReply reply; |
720 EXPECT_LE(sizeof(reply), server.MachMessageServerReplySize()); | 709 EXPECT_LE(sizeof(reply), server.MachMessageServerReplySize()); |
721 reply.InitializeForTesting(); | |
722 | 710 |
723 const exception_behavior_t kExceptionBehavior = | 711 const exception_behavior_t kExceptionBehavior = |
724 EXCEPTION_STATE | MACH_EXCEPTION_CODES; | 712 EXCEPTION_STATE | MACH_EXCEPTION_CODES; |
725 | 713 |
726 EXPECT_CALL( | 714 EXPECT_CALL( |
727 server, | 715 server, |
728 MockCatchMachException(kExceptionBehavior, | 716 MockCatchMachException(kExceptionBehavior, |
729 kServerLocalPort, | 717 kServerLocalPort, |
730 THREAD_NULL, | 718 THREAD_NULL, |
731 TASK_NULL, | 719 TASK_NULL, |
(...skipping 19 matching lines...) Expand all Loading... |
751 reply.Verify(kExceptionBehavior); | 739 reply.Verify(kExceptionBehavior); |
752 } | 740 } |
753 | 741 |
754 TEST(ExcServerVariants, MockMachExceptionRaiseStateIdentity) { | 742 TEST(ExcServerVariants, MockMachExceptionRaiseStateIdentity) { |
755 ScopedDefaultValue<kern_return_t> default_kern_return_t(KERN_FAILURE); | 743 ScopedDefaultValue<kern_return_t> default_kern_return_t(KERN_FAILURE); |
756 | 744 |
757 MockUniversalMachExcServer server; | 745 MockUniversalMachExcServer server; |
758 | 746 |
759 MachExceptionRaiseStateIdentityRequest request; | 747 MachExceptionRaiseStateIdentityRequest request; |
760 EXPECT_LE(sizeof(request), server.MachMessageServerRequestSize()); | 748 EXPECT_LE(sizeof(request), server.MachMessageServerRequestSize()); |
761 request.InitializeForTesting(); | |
762 | 749 |
763 MachExceptionRaiseStateIdentityReply reply; | 750 MachExceptionRaiseStateIdentityReply reply; |
764 EXPECT_LE(sizeof(reply), server.MachMessageServerReplySize()); | 751 EXPECT_LE(sizeof(reply), server.MachMessageServerReplySize()); |
765 reply.InitializeForTesting(); | |
766 | 752 |
767 const exception_behavior_t kExceptionBehavior = | 753 const exception_behavior_t kExceptionBehavior = |
768 EXCEPTION_STATE_IDENTITY | MACH_EXCEPTION_CODES; | 754 EXCEPTION_STATE_IDENTITY | MACH_EXCEPTION_CODES; |
769 | 755 |
770 EXPECT_CALL( | 756 EXPECT_CALL( |
771 server, | 757 server, |
772 MockCatchMachException(kExceptionBehavior, | 758 MockCatchMachException(kExceptionBehavior, |
773 kServerLocalPort, | 759 kServerLocalPort, |
774 kExceptionThreadPort, | 760 kExceptionThreadPort, |
775 kExceptionTaskPort, | 761 kExceptionTaskPort, |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
828 2506, | 814 2506, |
829 2507, | 815 2507, |
830 2508, | 816 2508, |
831 }; | 817 }; |
832 | 818 |
833 for (size_t index = 0; index < arraysize(unknown_ids); ++index) { | 819 for (size_t index = 0; index < arraysize(unknown_ids); ++index) { |
834 mach_msg_id_t id = unknown_ids[index]; | 820 mach_msg_id_t id = unknown_ids[index]; |
835 | 821 |
836 SCOPED_TRACE(base::StringPrintf("unknown id %d", id)); | 822 SCOPED_TRACE(base::StringPrintf("unknown id %d", id)); |
837 | 823 |
838 InvalidRequest request; | 824 InvalidRequest request(id); |
839 EXPECT_LE(sizeof(request), server.MachMessageServerRequestSize()); | 825 EXPECT_LE(sizeof(request), server.MachMessageServerRequestSize()); |
840 request.InitializeForTesting(id); | |
841 | 826 |
842 BadIDErrorReply reply; | 827 BadIDErrorReply reply; |
843 EXPECT_LE(sizeof(reply), server.MachMessageServerReplySize()); | 828 EXPECT_LE(sizeof(reply), server.MachMessageServerReplySize()); |
844 reply.InitializeForTesting(); | |
845 | 829 |
846 bool destroy_complex_request = false; | 830 bool destroy_complex_request = false; |
847 EXPECT_FALSE(server.MachMessageServerFunction( | 831 EXPECT_FALSE(server.MachMessageServerFunction( |
848 reinterpret_cast<mach_msg_header_t*>(&request), | 832 reinterpret_cast<mach_msg_header_t*>(&request), |
849 reinterpret_cast<mach_msg_header_t*>(&reply), | 833 reinterpret_cast<mach_msg_header_t*>(&reply), |
850 &destroy_complex_request)); | 834 &destroy_complex_request)); |
851 | 835 |
852 // The request wasn’t handled, nothing got a chance to change the value of | 836 // The request wasn’t handled, nothing got a chance to change the value of |
853 // this variable. MachMessageServer would destroy the request if it was | 837 // this variable. MachMessageServer would destroy the request if it was |
854 // complex, regardless of what was done to this variable, because the | 838 // complex, regardless of what was done to this variable, because the |
(...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1168 | 1152 |
1169 EXPECT_EQ(test_data.kr, | 1153 EXPECT_EQ(test_data.kr, |
1170 ExcServerSuccessfulReturnValue(test_data.behavior, | 1154 ExcServerSuccessfulReturnValue(test_data.behavior, |
1171 test_data.set_thread_state)); | 1155 test_data.set_thread_state)); |
1172 } | 1156 } |
1173 } | 1157 } |
1174 | 1158 |
1175 } // namespace | 1159 } // namespace |
1176 } // namespace test | 1160 } // namespace test |
1177 } // namespace crashpad | 1161 } // namespace crashpad |
OLD | NEW |