Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(341)

Side by Side Diff: util/mach/exc_server_variants.cc

Issue 766193006: exc_server_variants: Templatize and use CompositeMachMessageServer (Closed) Base URL: https://chromium.googlesource.com/crashpad/crashpad@master
Patch Set: Address review feedback Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « util/mach/exc_server_variants.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 <algorithm> 17 #include <algorithm>
18 #include <vector> 18 #include <vector>
19 19
20 #include "base/logging.h" 20 #include "base/logging.h"
21 #include "util/mach/composite_mach_message_server.h"
21 #include "util/mach/exc.h" 22 #include "util/mach/exc.h"
22 #include "util/mach/exception_behaviors.h" 23 #include "util/mach/exception_behaviors.h"
23 #include "util/mach/excServer.h" 24 #include "util/mach/excServer.h"
24 #include "util/mach/mach_exc.h" 25 #include "util/mach/mach_exc.h"
25 #include "util/mach/mach_excServer.h" 26 #include "util/mach/mach_excServer.h"
26 #include "util/mach/mach_message.h" 27 #include "util/mach/mach_message.h"
27 28
28 extern "C" { 29 extern "C" {
29 30
30 // These six functions are not used, and are in fact obsoleted by the other 31 // These six functions are not used, and are in fact obsoleted by the other
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
110 thread_state_t old_state, 111 thread_state_t old_state,
111 mach_msg_type_number_t old_state_count, 112 mach_msg_type_number_t old_state_count,
112 thread_state_t new_state, 113 thread_state_t new_state,
113 mach_msg_type_number_t* new_state_count) { 114 mach_msg_type_number_t* new_state_count) {
114 NOTREACHED(); 115 NOTREACHED();
115 return KERN_FAILURE; 116 return KERN_FAILURE;
116 } 117 }
117 118
118 } // extern "C" 119 } // extern "C"
119 120
121 namespace crashpad {
122
120 namespace { 123 namespace {
121 124
122 // There are no predefined constants for these. 125 // Traits for ExcServer<> and SimplifiedExcServer<> adapting them for use with
123 enum MachMessageID : mach_msg_id_t { 126 // the exc subsystem.
124 kMachMessageIDExceptionRaise = 2401, 127 struct ExcTraits {
125 kMachMessageIDExceptionRaiseState = 2402, 128 using ExceptionCode = exception_data_type_t;
126 kMachMessageIDExceptionRaiseStateIdentity = 2403, 129
127 kMachMessageIDMachExceptionRaise = 2405, 130 using RequestUnion = __RequestUnion__exc_subsystem;
128 kMachMessageIDMachExceptionRaiseState = 2406, 131 using ReplyUnion = __ReplyUnion__exc_subsystem;
129 kMachMessageIDMachExceptionRaiseStateIdentity = 2407, 132
133 using ExceptionRaiseRequest = __Request__exception_raise_t;
134 using ExceptionRaiseStateRequest = __Request__exception_raise_state_t;
135 using ExceptionRaiseStateIdentityRequest =
136 __Request__exception_raise_state_identity_t;
137
138 using ExceptionRaiseReply = __Reply__exception_raise_t;
139 using ExceptionRaiseStateReply = __Reply__exception_raise_state_t;
140 using ExceptionRaiseStateIdentityReply =
141 __Reply__exception_raise_state_identity_t;
142
143 // The MIG-generated __MIG_check__Request__*() functions are not declared as
144 // accepting const data, but they could have been because they in fact do not
145 // modify the data.
146
147 static kern_return_t MIGCheckRequestExceptionRaise(
148 const ExceptionRaiseRequest* in_request) {
149 return __MIG_check__Request__exception_raise_t(
150 const_cast<ExceptionRaiseRequest*>(in_request));
151 }
152
153 static kern_return_t MIGCheckRequestExceptionRaiseState(
154 const ExceptionRaiseStateRequest* in_request,
155 const ExceptionRaiseStateRequest** in_request_1) {
156 using Request = __Request__exception_raise_state_t;
157 return __MIG_check__Request__exception_raise_state_t(
158 const_cast<ExceptionRaiseStateRequest*>(in_request),
159 const_cast<ExceptionRaiseStateRequest**>(in_request_1));
160 }
161
162 static kern_return_t MIGCheckRequestExceptionRaiseStateIdentity(
163 const ExceptionRaiseStateIdentityRequest* in_request,
164 const ExceptionRaiseStateIdentityRequest** in_request_1) {
165 return __MIG_check__Request__exception_raise_state_identity_t(
166 const_cast<ExceptionRaiseStateIdentityRequest*>(in_request),
167 const_cast<ExceptionRaiseStateIdentityRequest**>(in_request_1));
168 }
169
170 // There are no predefined constants for these.
171 static const mach_msg_id_t kMachMessageIDExceptionRaise = 2401;
172 static const mach_msg_id_t kMachMessageIDExceptionRaiseState = 2402;
173 static const mach_msg_id_t kMachMessageIDExceptionRaiseStateIdentity = 2403;
174
175 static const exception_behavior_t kExceptionBehavior = 0;
130 }; 176 };
131 177
132 // The MIG-generated __MIG_check__Request__*() functions are not declared as 178 // Traits for ExcServer<> and SimplifiedExcServer<> adapting them for use with
133 // accepting const data, but they could have been because they in fact do not 179 // the mach_exc subsystem.
134 // modify the data. These wrapper functions are provided to bridge the const gap 180 struct MachExcTraits {
135 // between the code in this file, which is const-correct and treats request 181 using ExceptionCode = mach_exception_data_type_t;
136 // message data as const, and those generated functions. 182
137 183 using RequestUnion = __RequestUnion__mach_exc_subsystem;
138 kern_return_t MIGCheckRequestExceptionRaise( 184 using ReplyUnion = __ReplyUnion__mach_exc_subsystem;
139 const __Request__exception_raise_t* in_request) { 185
140 using Request = __Request__exception_raise_t; 186 using ExceptionRaiseRequest = __Request__mach_exception_raise_t;
141 return __MIG_check__Request__exception_raise_t( 187 using ExceptionRaiseStateRequest = __Request__mach_exception_raise_state_t;
142 const_cast<Request*>(in_request)); 188 using ExceptionRaiseStateIdentityRequest =
143 } 189 __Request__mach_exception_raise_state_identity_t;
144 190
145 kern_return_t MIGCheckRequestExceptionRaiseState( 191 using ExceptionRaiseReply = __Reply__mach_exception_raise_t;
146 const __Request__exception_raise_state_t* in_request, 192 using ExceptionRaiseStateReply = __Reply__mach_exception_raise_state_t;
147 const __Request__exception_raise_state_t** in_request_1) { 193 using ExceptionRaiseStateIdentityReply =
148 using Request = __Request__exception_raise_state_t; 194 __Reply__mach_exception_raise_state_identity_t;
149 return __MIG_check__Request__exception_raise_state_t( 195
150 const_cast<Request*>(in_request), const_cast<Request**>(in_request_1)); 196 // The MIG-generated __MIG_check__Request__*() functions are not declared as
151 } 197 // accepting const data, but they could have been because they in fact do not
152 198 // modify the data.
153 kern_return_t MIGCheckRequestExceptionRaiseStateIdentity( 199
154 const __Request__exception_raise_state_identity_t* in_request, 200 static kern_return_t MIGCheckRequestExceptionRaise(
155 const __Request__exception_raise_state_identity_t** in_request_1) { 201 const ExceptionRaiseRequest* in_request) {
156 using Request = __Request__exception_raise_state_identity_t; 202 return __MIG_check__Request__mach_exception_raise_t(
157 return __MIG_check__Request__exception_raise_state_identity_t( 203 const_cast<ExceptionRaiseRequest*>(in_request));
158 const_cast<Request*>(in_request), const_cast<Request**>(in_request_1)); 204 }
159 } 205
160 206 static kern_return_t MIGCheckRequestExceptionRaiseState(
161 kern_return_t MIGCheckRequestMachExceptionRaise( 207 const ExceptionRaiseStateRequest* in_request,
162 const __Request__mach_exception_raise_t* in_request) { 208 const ExceptionRaiseStateRequest** in_request_1) {
163 using Request = __Request__mach_exception_raise_t; 209 using Request = __Request__exception_raise_state_t;
164 return __MIG_check__Request__mach_exception_raise_t( 210 return __MIG_check__Request__mach_exception_raise_state_t(
165 const_cast<Request*>(in_request)); 211 const_cast<ExceptionRaiseStateRequest*>(in_request),
166 } 212 const_cast<ExceptionRaiseStateRequest**>(in_request_1));
167 213 }
168 kern_return_t MIGCheckRequestMachExceptionRaiseState( 214
169 const __Request__mach_exception_raise_state_t* in_request, 215 static kern_return_t MIGCheckRequestExceptionRaiseStateIdentity(
170 const __Request__mach_exception_raise_state_t** in_request_1) { 216 const ExceptionRaiseStateIdentityRequest* in_request,
171 using Request = __Request__mach_exception_raise_state_t; 217 const ExceptionRaiseStateIdentityRequest** in_request_1) {
172 return __MIG_check__Request__mach_exception_raise_state_t( 218 return __MIG_check__Request__mach_exception_raise_state_identity_t(
173 const_cast<Request*>(in_request), const_cast<Request**>(in_request_1)); 219 const_cast<ExceptionRaiseStateIdentityRequest*>(in_request),
174 } 220 const_cast<ExceptionRaiseStateIdentityRequest**>(in_request_1));
175 221 }
176 kern_return_t MIGCheckRequestMachExceptionRaiseStateIdentity( 222
177 const __Request__mach_exception_raise_state_identity_t* in_request, 223 // There are no predefined constants for these.
178 const __Request__mach_exception_raise_state_identity_t** in_request_1) { 224 static const mach_msg_id_t kMachMessageIDExceptionRaise = 2405;
179 using Request = __Request__mach_exception_raise_state_identity_t; 225 static const mach_msg_id_t kMachMessageIDExceptionRaiseState = 2406;
180 return __MIG_check__Request__mach_exception_raise_state_identity_t( 226 static const mach_msg_id_t kMachMessageIDExceptionRaiseStateIdentity = 2407;
181 const_cast<Request*>(in_request), const_cast<Request**>(in_request_1)); 227
182 } 228 static const exception_behavior_t kExceptionBehavior = MACH_EXCEPTION_CODES;
183 229 };
184 } // namespace 230
185 231 //! \brief A server interface for the `exc` or `mach_exc` Mach subsystems.
186 namespace crashpad { 232 template <typename Traits>
187 namespace internal { 233 class ExcServer : public MachMessageServer::Interface {
188 234 public:
189 ExcServer::ExcServer(ExcServer::Interface* interface) 235 //! \brief An interface that the different request messages that are a part of
190 : MachMessageServer::Interface(), 236 //! the `exc` or `mach_exc` Mach subsystems can be dispatched to.
191 interface_(interface) { 237 class Interface {
192 } 238 public:
193 239 //! \brief Handles exceptions raised by `exception_raise()` or
194 bool ExcServer::MachMessageServerFunction(const mach_msg_header_t* in_header, 240 //! `mach_exception_raise()`.
195 mach_msg_header_t* out_header, 241 //!
196 bool* destroy_complex_request) { 242 //! This behaves equivalently to a `catch_exception_raise()` function used
243 //! with `exc_server()`, or a `catch_mach_exception_raise()` function used
244 //! with `mach_exc_server()`.
245 //!
246 //! \param[in] trailer The trailer received with the request message.
247 //! \param[out] destroy_request `true` if the request message is to be
248 //! destroyed even when this method returns success. See
249 //! MachMessageServer::Interface.
250 virtual kern_return_t CatchExceptionRaise(
251 exception_handler_t exception_port,
252 thread_t thread,
253 task_t task,
254 exception_type_t exception,
255 const typename Traits::ExceptionCode* code,
256 mach_msg_type_number_t code_count,
257 const mach_msg_trailer_t* trailer,
258 bool* destroy_request) = 0;
259
260 //! \brief Handles exceptions raised by `exception_raise_state()` or
261 //! `mach_exception_raise_state()`.
262 //!
263 //! This behaves equivalently to a `catch_exception_raise_state()` function
264 //! used with `exc_server()`, or a `catch_mach_exception_raise_state()`
265 //! function used with `mach_exc_server()`.
266 //!
267 //! There is no \a destroy_request parameter because, unlike
268 //! CatchExceptionRaise() and CatchExceptionRaiseStateIdentity(), the
269 //! request message is not complex (it does not carry the \a thread or \a
270 //! task port rights) and thus there is nothing to destroy.
271 //!
272 //! \param[in] trailer The trailer received with the request message.
273 virtual kern_return_t CatchExceptionRaiseState(
274 exception_handler_t exception_port,
275 exception_type_t exception,
276 const typename Traits::ExceptionCode* code,
277 mach_msg_type_number_t code_count,
278 thread_state_flavor_t* flavor,
279 const natural_t* old_state,
280 mach_msg_type_number_t old_state_count,
281 thread_state_t new_state,
282 mach_msg_type_number_t* new_state_count,
283 const mach_msg_trailer_t* trailer) = 0;
284
285 //! \brief Handles exceptions raised by `exception_raise_state_identity()`
286 //! or `mach_exception_raise_state_identity()`.
287 //!
288 //! This behaves equivalently to a `catch_exception_raise_state_identity()`
289 //! function used with `exc_server()`, or a
290 //! `catch_mach_exception_raise_state_identity()` function used with
291 //! `mach_exc_server()`.
292 //!
293 //! \param[in] trailer The trailer received with the request message.
294 //! \param[out] destroy_request `true` if the request message is to be
295 //! destroyed even when this method returns success. See
296 //! MachMessageServer::Interface.
297 virtual kern_return_t CatchExceptionRaiseStateIdentity(
298 exception_handler_t exception_port,
299 thread_t thread,
300 task_t task,
301 exception_type_t exception,
302 const typename Traits::ExceptionCode* code,
303 mach_msg_type_number_t code_count,
304 thread_state_flavor_t* flavor,
305 const natural_t* old_state,
306 mach_msg_type_number_t old_state_count,
307 thread_state_t new_state,
308 mach_msg_type_number_t* new_state_count,
309 const mach_msg_trailer_t* trailer,
310 bool* destroy_request) = 0;
311
312 protected:
313 ~Interface() {}
314 };
315
316 //! \brief Constructs an object of this class.
317 //!
318 //! \param[in] interface The interface to dispatch requests to. Weak.
319 explicit ExcServer(Interface* interface)
320 : MachMessageServer::Interface(), interface_(interface) {}
321
322 // MachMessageServer::Interface:
323
324 bool MachMessageServerFunction(const mach_msg_header_t* in_header,
325 mach_msg_header_t* out_header,
326 bool* destroy_complex_request) override;
327
328 std::set<mach_msg_id_t> MachMessageServerRequestIDs() override {
329 const mach_msg_id_t request_ids[] = {
330 Traits::kMachMessageIDExceptionRaise,
331 Traits::kMachMessageIDExceptionRaiseState,
332 Traits::kMachMessageIDExceptionRaiseStateIdentity,
333 };
334 return std::set<mach_msg_id_t>(&request_ids[0],
335 &request_ids[arraysize(request_ids)]);
336 }
337
338 mach_msg_size_t MachMessageServerRequestSize() override {
339 return sizeof(typename Traits::RequestUnion);
340 }
341
342 mach_msg_size_t MachMessageServerReplySize() override {
343 return sizeof(typename Traits::ReplyUnion);
344 }
345
346 private:
347 Interface* interface_; // weak
348
349 DISALLOW_COPY_AND_ASSIGN(ExcServer);
350 };
351
352 template <typename Traits>
353 bool ExcServer<Traits>::MachMessageServerFunction(
354 const mach_msg_header_t* in_header,
355 mach_msg_header_t* out_header,
356 bool* destroy_complex_request) {
197 PrepareMIGReplyFromRequest(in_header, out_header); 357 PrepareMIGReplyFromRequest(in_header, out_header);
198 358
199 const mach_msg_trailer_t* in_trailer = 359 const mach_msg_trailer_t* in_trailer =
200 MachMessageTrailerFromHeader(in_header); 360 MachMessageTrailerFromHeader(in_header);
201 361
202 switch (in_header->msgh_id) { 362 switch (in_header->msgh_id) {
203 case kMachMessageIDExceptionRaise: { 363 case Traits::kMachMessageIDExceptionRaise: {
204 // exception_raise(), catch_exception_raise(). 364 // exception_raise(), catch_exception_raise(), mach_exception_raise(),
205 using Request = __Request__exception_raise_t; 365 // catch_mach_exception_raise().
366 using Request = typename Traits::ExceptionRaiseRequest;
206 const Request* in_request = reinterpret_cast<const Request*>(in_header); 367 const Request* in_request = reinterpret_cast<const Request*>(in_header);
207 kern_return_t kr = MIGCheckRequestExceptionRaise(in_request); 368 kern_return_t kr = Traits::MIGCheckRequestExceptionRaise(in_request);
208 if (kr != MACH_MSG_SUCCESS) { 369 if (kr != MACH_MSG_SUCCESS) {
209 SetMIGReplyError(out_header, kr); 370 SetMIGReplyError(out_header, kr);
210 return true; 371 return true;
211 } 372 }
212 373
213 using Reply = __Reply__exception_raise_t; 374 using Reply = typename Traits::ExceptionRaiseReply;
214 Reply* out_reply = reinterpret_cast<Reply*>(out_header); 375 Reply* out_reply = reinterpret_cast<Reply*>(out_header);
215 out_reply->RetCode = 376 out_reply->RetCode =
216 interface_->CatchExceptionRaise(in_header->msgh_local_port, 377 interface_->CatchExceptionRaise(in_header->msgh_local_port,
217 in_request->thread.name, 378 in_request->thread.name,
218 in_request->task.name, 379 in_request->task.name,
219 in_request->exception, 380 in_request->exception,
220 in_request->code, 381 in_request->code,
221 in_request->codeCnt, 382 in_request->codeCnt,
222 in_trailer, 383 in_trailer,
223 destroy_complex_request); 384 destroy_complex_request);
224 if (out_reply->RetCode != KERN_SUCCESS) { 385 if (out_reply->RetCode != KERN_SUCCESS) {
225 return true; 386 return true;
226 } 387 }
227 388
228 out_header->msgh_size = sizeof(*out_reply); 389 out_header->msgh_size = sizeof(*out_reply);
229 return true; 390 return true;
230 } 391 }
231 392
232 case kMachMessageIDExceptionRaiseState: { 393 case Traits::kMachMessageIDExceptionRaiseState: {
233 // exception_raise_state(), catch_exception_raise_state(). 394 // exception_raise_state(), catch_exception_raise_state(),
234 using Request = __Request__exception_raise_state_t; 395 // mach_exception_raise_state(), catch_mach_exception_raise_state().
396 using Request = typename Traits::ExceptionRaiseStateRequest;
235 const Request* in_request = reinterpret_cast<const Request*>(in_header); 397 const Request* in_request = reinterpret_cast<const Request*>(in_header);
236 398
237 // in_request_1 is used for the portion of the request after the codes, 399 // in_request_1 is used for the portion of the request after the codes,
238 // which in theory can be variable-length. The check function will set it. 400 // which in theory can be variable-length. The check function will set it.
239 const Request* in_request_1; 401 const Request* in_request_1;
240 kern_return_t kr = 402 kern_return_t kr =
241 MIGCheckRequestExceptionRaiseState(in_request, &in_request_1); 403 Traits::MIGCheckRequestExceptionRaiseState(in_request, &in_request_1);
242 if (kr != MACH_MSG_SUCCESS) { 404 if (kr != MACH_MSG_SUCCESS) {
243 SetMIGReplyError(out_header, kr); 405 SetMIGReplyError(out_header, kr);
244 return true; 406 return true;
245 } 407 }
246 408
247 using Reply = __Reply__exception_raise_state_t; 409 using Reply = typename Traits::ExceptionRaiseStateReply;
248 Reply* out_reply = reinterpret_cast<Reply*>(out_header); 410 Reply* out_reply = reinterpret_cast<Reply*>(out_header);
249 out_reply->flavor = in_request_1->flavor; 411 out_reply->flavor = in_request_1->flavor;
250 out_reply->new_stateCnt = arraysize(out_reply->new_state); 412 out_reply->new_stateCnt = arraysize(out_reply->new_state);
251 out_reply->RetCode = 413 out_reply->RetCode =
252 interface_->CatchExceptionRaiseState(in_header->msgh_local_port, 414 interface_->CatchExceptionRaiseState(in_header->msgh_local_port,
253 in_request->exception, 415 in_request->exception,
254 in_request->code, 416 in_request->code,
255 in_request->codeCnt, 417 in_request->codeCnt,
256 &out_reply->flavor, 418 &out_reply->flavor,
257 in_request_1->old_state, 419 in_request_1->old_state,
258 in_request_1->old_stateCnt, 420 in_request_1->old_stateCnt,
259 out_reply->new_state, 421 out_reply->new_state,
260 &out_reply->new_stateCnt, 422 &out_reply->new_stateCnt,
261 in_trailer); 423 in_trailer);
262 if (out_reply->RetCode != KERN_SUCCESS) { 424 if (out_reply->RetCode != KERN_SUCCESS) {
263 return true; 425 return true;
264 } 426 }
265 427
266 out_header->msgh_size = 428 out_header->msgh_size =
267 sizeof(*out_reply) - sizeof(out_reply->new_state) + 429 sizeof(*out_reply) - sizeof(out_reply->new_state) +
268 sizeof(out_reply->new_state[0]) * out_reply->new_stateCnt; 430 sizeof(out_reply->new_state[0]) * out_reply->new_stateCnt;
269 return true; 431 return true;
270 } 432 }
271 433
272 case kMachMessageIDExceptionRaiseStateIdentity: { 434 case Traits::kMachMessageIDExceptionRaiseStateIdentity: {
273 // exception_raise_state_identity(), 435 // exception_raise_state_identity(),
274 // catch_exception_raise_state_identity(). 436 // catch_exception_raise_state_identity(),
275 using Request = __Request__exception_raise_state_identity_t; 437 // mach_exception_raise_state_identity(),
438 // catch_mach_exception_raise_state_identity().
439 using Request = typename Traits::ExceptionRaiseStateIdentityRequest;
276 const Request* in_request = reinterpret_cast<const Request*>(in_header); 440 const Request* in_request = reinterpret_cast<const Request*>(in_header);
277 441
278 // in_request_1 is used for the portion of the request after the codes, 442 // in_request_1 is used for the portion of the request after the codes,
279 // which in theory can be variable-length. The check function will set it. 443 // which in theory can be variable-length. The check function will set it.
280 const Request* in_request_1; 444 const Request* in_request_1;
281 kern_return_t kr = 445 kern_return_t kr = Traits::MIGCheckRequestExceptionRaiseStateIdentity(
282 MIGCheckRequestExceptionRaiseStateIdentity(in_request, &in_request_1); 446 in_request, &in_request_1);
283 if (kr != MACH_MSG_SUCCESS) { 447 if (kr != MACH_MSG_SUCCESS) {
284 SetMIGReplyError(out_header, kr); 448 SetMIGReplyError(out_header, kr);
285 return true; 449 return true;
286 } 450 }
287 451
288 using Reply = __Reply__exception_raise_state_identity_t; 452 using Reply = typename Traits::ExceptionRaiseStateIdentityReply;
289 Reply* out_reply = reinterpret_cast<Reply*>(out_header); 453 Reply* out_reply = reinterpret_cast<Reply*>(out_header);
290 out_reply->flavor = in_request_1->flavor; 454 out_reply->flavor = in_request_1->flavor;
291 out_reply->new_stateCnt = arraysize(out_reply->new_state); 455 out_reply->new_stateCnt = arraysize(out_reply->new_state);
292 out_reply->RetCode = interface_->CatchExceptionRaiseStateIdentity( 456 out_reply->RetCode = interface_->CatchExceptionRaiseStateIdentity(
293 in_header->msgh_local_port, 457 in_header->msgh_local_port,
294 in_request->thread.name, 458 in_request->thread.name,
295 in_request->task.name, 459 in_request->task.name,
296 in_request->exception, 460 in_request->exception,
297 in_request->code, 461 in_request->code,
298 in_request->codeCnt, 462 in_request->codeCnt,
(...skipping 12 matching lines...) Expand all
311 sizeof(*out_reply) - sizeof(out_reply->new_state) + 475 sizeof(*out_reply) - sizeof(out_reply->new_state) +
312 sizeof(out_reply->new_state[0]) * out_reply->new_stateCnt; 476 sizeof(out_reply->new_state[0]) * out_reply->new_stateCnt;
313 return true; 477 return true;
314 } 478 }
315 } 479 }
316 480
317 SetMIGReplyError(out_header, MIG_BAD_ID); 481 SetMIGReplyError(out_header, MIG_BAD_ID);
318 return false; 482 return false;
319 } 483 }
320 484
321 std::set<mach_msg_id_t> ExcServer::MachMessageServerRequestIDs() { 485 //! \brief A server interface for the `exc` or `mach_exc` Mach subsystems,
322 const mach_msg_id_t request_ids[] = { 486 //! simplified to have only a single interface method needing
323 kMachMessageIDExceptionRaise, 487 //! implementation.
324 kMachMessageIDExceptionRaiseState, 488 template <typename Traits>
325 kMachMessageIDExceptionRaiseStateIdentity 489 class SimplifiedExcServer final : public ExcServer<Traits>,
490 public ExcServer<Traits>::Interface {
491 public:
492 //! \brief An interface that the different request messages that are a part of
493 //! the `exc` or `mach_exc` Mach subsystems can be dispatched to.
494 class Interface {
495 public:
496 //! \brief Handles exceptions raised by `exception_raise()`,
497 //! `exception_raise_state()`, and `exception_raise_state_identity()`;
498 //! or `mach_exception_raise()`, `mach_exception_raise_state()`, and
499 //! `mach_exception_raise_state_identity()`.
500 //!
501 //! For convenience in implementation, these different “behaviors” of
502 //! exception messages are all mapped to a single interface method. The
503 //! exception’s original “behavior” is specified in the \a behavior
504 //! parameter. Only parameters that were supplied in the request message
505 //! are populated, other parameters are set to reasonable default values.
506 //!
507 //! The meanings of most parameters are identical to that of
508 //! ExcServer<>::Interface::CatchExceptionRaiseStateIdentity().
509 //!
510 //! \param[in] behavior `EXCEPTION_DEFAULT`, `EXCEPTION_STATE`, or
511 //! `EXCEPTION_STATE_IDENTITY`, identifying which exception request
512 //! message was processed and thus which other parameters are valid.
513 //! When used with the `mach_exc` subsystem, `MACH_EXCEPTION_CODES` will
514 //! be ORed in to this parameter.
515 virtual kern_return_t CatchException(
516 exception_behavior_t behavior,
517 exception_handler_t exception_port,
518 thread_t thread,
519 task_t task,
520 exception_type_t exception,
521 const typename Traits::ExceptionCode* code,
522 mach_msg_type_number_t code_count,
523 thread_state_flavor_t* flavor,
524 const natural_t* old_state,
525 mach_msg_type_number_t old_state_count,
526 thread_state_t new_state,
527 mach_msg_type_number_t* new_state_count,
528 const mach_msg_trailer_t* trailer,
529 bool* destroy_complex_request) = 0;
530
531 protected:
532 ~Interface() {}
326 }; 533 };
327 return std::set<mach_msg_id_t>( 534
328 &request_ids[0], &request_ids[arraysize(request_ids)]); 535 //! \brief Constructs an object of this class.
329 } 536 //!
330 537 //! \param[in] interface The interface to dispatch requests to. Weak.
331 mach_msg_size_t ExcServer::MachMessageServerRequestSize() { 538 explicit SimplifiedExcServer(Interface* interface)
332 return sizeof(__RequestUnion__exc_subsystem); 539 : ExcServer<Traits>(this),
333 } 540 ExcServer<Traits>::Interface(),
334 541 interface_(interface) {}
335 mach_msg_size_t ExcServer::MachMessageServerReplySize() { 542
336 return sizeof(__ReplyUnion__exc_subsystem); 543 // ExcServer::Interface:
337 } 544
338 545 kern_return_t CatchExceptionRaise(exception_handler_t exception_port,
339 MachExcServer::MachExcServer(MachExcServer::Interface* interface) 546 thread_t thread,
340 : MachMessageServer::Interface(), 547 task_t task,
341 interface_(interface) { 548 exception_type_t exception,
342 } 549 const typename Traits::ExceptionCode* code,
343 550 mach_msg_type_number_t code_count,
344 bool MachExcServer::MachMessageServerFunction( 551 const mach_msg_trailer_t* trailer,
345 const mach_msg_header_t* in_header, 552 bool* destroy_request) override {
346 mach_msg_header_t* out_header, 553 thread_state_flavor_t flavor = THREAD_STATE_NONE;
347 bool* destroy_complex_request) { 554 mach_msg_type_number_t new_state_count = 0;
348 PrepareMIGReplyFromRequest(in_header, out_header); 555 return interface_->CatchException(
349 556 Traits::kExceptionBehavior | EXCEPTION_DEFAULT,
350 const mach_msg_trailer_t* in_trailer = 557 exception_port,
351 MachMessageTrailerFromHeader(in_header); 558 thread,
352 559 task,
353 switch (in_header->msgh_id) { 560 exception,
354 case kMachMessageIDMachExceptionRaise: { 561 code_count ? code : nullptr,
355 // mach_exception_raise(), catch_mach_exception_raise(). 562 code_count,
356 using Request = __Request__mach_exception_raise_t; 563 &flavor,
357 const Request* in_request = reinterpret_cast<const Request*>(in_header); 564 nullptr,
358 kern_return_t kr = MIGCheckRequestMachExceptionRaise(in_request); 565 0,
359 if (kr != MACH_MSG_SUCCESS) { 566 nullptr,
360 SetMIGReplyError(out_header, kr); 567 &new_state_count,
361 return true; 568 trailer,
362 } 569 destroy_request);
363 570 }
364 using Reply = __Reply__mach_exception_raise_t; 571
365 Reply* out_reply = reinterpret_cast<Reply*>(out_header); 572 kern_return_t CatchExceptionRaiseState(
366 out_reply->RetCode = 573 exception_handler_t exception_port,
367 interface_->CatchMachExceptionRaise(in_header->msgh_local_port, 574 exception_type_t exception,
368 in_request->thread.name, 575 const typename Traits::ExceptionCode* code,
369 in_request->task.name, 576 mach_msg_type_number_t code_count,
370 in_request->exception, 577 thread_state_flavor_t* flavor,
371 in_request->code, 578 const natural_t* old_state,
372 in_request->codeCnt, 579 mach_msg_type_number_t old_state_count,
373 in_trailer, 580 thread_state_t new_state,
374 destroy_complex_request); 581 mach_msg_type_number_t* new_state_count,
375 if (out_reply->RetCode != KERN_SUCCESS) { 582 const mach_msg_trailer_t* trailer) override {
376 return true; 583 bool destroy_complex_request = false;
377 } 584 return interface_->CatchException(
378 585 Traits::kExceptionBehavior | EXCEPTION_STATE,
379 out_header->msgh_size = sizeof(*out_reply); 586 exception_port,
380 return true; 587 THREAD_NULL,
588 TASK_NULL,
589 exception,
590 code_count ? code : nullptr,
591 code_count,
592 flavor,
593 old_state_count ? old_state : nullptr,
594 old_state_count,
595 new_state_count ? new_state : nullptr,
596 new_state_count,
597 trailer,
598 &destroy_complex_request);
599 }
600
601 kern_return_t CatchExceptionRaiseStateIdentity(
602 exception_handler_t exception_port,
603 thread_t thread,
604 task_t task,
605 exception_type_t exception,
606 const typename Traits::ExceptionCode* code,
607 mach_msg_type_number_t code_count,
608 thread_state_flavor_t* flavor,
609 const natural_t* old_state,
610 mach_msg_type_number_t old_state_count,
611 thread_state_t new_state,
612 mach_msg_type_number_t* new_state_count,
613 const mach_msg_trailer_t* trailer,
614 bool* destroy_request) override {
615 return interface_->CatchException(
616 Traits::kExceptionBehavior | EXCEPTION_STATE_IDENTITY,
617 exception_port,
618 thread,
619 task,
620 exception,
621 code_count ? code : nullptr,
622 code_count,
623 flavor,
624 old_state_count ? old_state : nullptr,
625 old_state_count,
626 new_state_count ? new_state : nullptr,
627 new_state_count,
628 trailer,
629 destroy_request);
630 }
631
632 private:
633 Interface* interface_; // weak
634
635 DISALLOW_COPY_AND_ASSIGN(SimplifiedExcServer);
636 };
637
638 } // namespace
639
640 namespace internal {
641
642 class UniversalMachExcServerImpl final
643 : public CompositeMachMessageServer,
644 public SimplifiedExcServer<ExcTraits>::Interface,
645 public SimplifiedExcServer<MachExcTraits>::Interface {
646 public:
647 explicit UniversalMachExcServerImpl(
648 UniversalMachExcServer::Interface* interface)
649 : CompositeMachMessageServer(),
650 SimplifiedExcServer<ExcTraits>::Interface(),
651 SimplifiedExcServer<MachExcTraits>::Interface(),
652 exc_server_(this),
653 mach_exc_server_(this),
654 interface_(interface) {
655 AddHandler(&exc_server_);
656 AddHandler(&mach_exc_server_);
657 }
658
659 ~UniversalMachExcServerImpl() {}
660
661 // SimplifiedExcServer<ExcTraits>::Interface:
662 kern_return_t CatchException(exception_behavior_t behavior,
663 exception_handler_t exception_port,
664 thread_t thread,
665 task_t task,
666 exception_type_t exception,
667 const exception_data_type_t* code,
668 mach_msg_type_number_t code_count,
669 thread_state_flavor_t* flavor,
670 const natural_t* old_state,
671 mach_msg_type_number_t old_state_count,
672 thread_state_t new_state,
673 mach_msg_type_number_t* new_state_count,
674 const mach_msg_trailer_t* trailer,
675 bool* destroy_complex_request) {
676 std::vector<mach_exception_data_type_t> mach_codes;
677 mach_codes.reserve(code_count);
678 for (size_t index = 0; index < code_count; ++index) {
679 mach_codes.push_back(code[index]);
381 } 680 }
382 681
383 case kMachMessageIDMachExceptionRaiseState: { 682 return interface_->CatchMachException(behavior,
384 // mach_exception_raise_state(), catch_mach_exception_raise_state(). 683 exception_port,
385 using Request = __Request__mach_exception_raise_state_t; 684 thread,
386 const Request* in_request = reinterpret_cast<const Request*>(in_header); 685 task,
387 686 exception,
388 // in_request_1 is used for the portion of the request after the codes, 687 code_count ? &mach_codes[0] : nullptr,
389 // which in theory can be variable-length. The check function will set it. 688 code_count,
390 const Request* in_request_1; 689 flavor,
391 kern_return_t kr = 690 old_state_count ? old_state : nullptr,
392 MIGCheckRequestMachExceptionRaiseState(in_request, &in_request_1); 691 old_state_count,
393 if (kr != MACH_MSG_SUCCESS) { 692 new_state_count ? new_state : nullptr,
394 SetMIGReplyError(out_header, kr); 693 new_state_count,
395 return true; 694 trailer,
396 } 695 destroy_complex_request);
397 696 }
398 using Reply = __Reply__mach_exception_raise_state_t; 697
399 Reply* out_reply = reinterpret_cast<Reply*>(out_header); 698 // SimplifiedExcServer<MachExcTraits>::Interface:
400 out_reply->flavor = in_request_1->flavor; 699 kern_return_t CatchException(exception_behavior_t behavior,
401 out_reply->new_stateCnt = arraysize(out_reply->new_state); 700 exception_handler_t exception_port,
402 out_reply->RetCode = 701 thread_t thread,
403 interface_->CatchMachExceptionRaiseState(in_header->msgh_local_port, 702 task_t task,
404 in_request->exception, 703 exception_type_t exception,
405 in_request->code, 704 const mach_exception_data_type_t* code,
406 in_request->codeCnt, 705 mach_msg_type_number_t code_count,
407 &out_reply->flavor, 706 thread_state_flavor_t* flavor,
408 in_request_1->old_state, 707 const natural_t* old_state,
409 in_request_1->old_stateCnt, 708 mach_msg_type_number_t old_state_count,
410 out_reply->new_state, 709 thread_state_t new_state,
411 &out_reply->new_stateCnt, 710 mach_msg_type_number_t* new_state_count,
412 in_trailer); 711 const mach_msg_trailer_t* trailer,
413 if (out_reply->RetCode != KERN_SUCCESS) { 712 bool* destroy_complex_request) {
414 return true; 713 return interface_->CatchMachException(behavior,
415 } 714 exception_port,
416 715 thread,
417 out_header->msgh_size = 716 task,
418 sizeof(*out_reply) - sizeof(out_reply->new_state) + 717 exception,
419 sizeof(out_reply->new_state[0]) * out_reply->new_stateCnt; 718 code_count ? code : nullptr,
420 return true; 719 code_count,
421 } 720 flavor,
422 721 old_state_count ? old_state : nullptr,
423 case kMachMessageIDMachExceptionRaiseStateIdentity: { 722 old_state_count,
424 // mach_exception_raise_state_identity(), 723 new_state_count ? new_state : nullptr,
425 // catch_mach_exception_raise_state_identity(). 724 new_state_count,
426 using Request = __Request__mach_exception_raise_state_identity_t; 725 trailer,
427 const Request* in_request = reinterpret_cast<const Request*>(in_header); 726 destroy_complex_request);
428 727 }
429 // in_request_1 is used for the portion of the request after the codes, 728
430 // which in theory can be variable-length. The check function will set it. 729 private:
431 const Request* in_request_1; 730 SimplifiedExcServer<ExcTraits> exc_server_;
432 kern_return_t kr = MIGCheckRequestMachExceptionRaiseStateIdentity( 731 SimplifiedExcServer<MachExcTraits> mach_exc_server_;
433 in_request, &in_request_1); 732 UniversalMachExcServer::Interface* interface_; // weak
434 if (kr != MACH_MSG_SUCCESS) { 733
435 SetMIGReplyError(out_header, kr); 734 DISALLOW_COPY_AND_ASSIGN(UniversalMachExcServerImpl);
436 return true; 735 };
437 }
438
439 using Reply = __Reply__mach_exception_raise_state_identity_t;
440 Reply* out_reply = reinterpret_cast<Reply*>(out_header);
441 out_reply->flavor = in_request_1->flavor;
442 out_reply->new_stateCnt = arraysize(out_reply->new_state);
443 out_reply->RetCode = interface_->CatchMachExceptionRaiseStateIdentity(
444 in_header->msgh_local_port,
445 in_request->thread.name,
446 in_request->task.name,
447 in_request->exception,
448 in_request->code,
449 in_request->codeCnt,
450 &out_reply->flavor,
451 in_request_1->old_state,
452 in_request_1->old_stateCnt,
453 out_reply->new_state,
454 &out_reply->new_stateCnt,
455 in_trailer,
456 destroy_complex_request);
457 if (out_reply->RetCode != KERN_SUCCESS) {
458 return true;
459 }
460
461 out_header->msgh_size =
462 sizeof(*out_reply) - sizeof(out_reply->new_state) +
463 sizeof(out_reply->new_state[0]) * out_reply->new_stateCnt;
464 return true;
465 }
466 }
467
468 SetMIGReplyError(out_header, MIG_BAD_ID);
469 return false;
470 }
471
472 std::set<mach_msg_id_t> MachExcServer::MachMessageServerRequestIDs() {
473 const mach_msg_id_t request_ids[] = {
474 kMachMessageIDMachExceptionRaise,
475 kMachMessageIDMachExceptionRaiseState,
476 kMachMessageIDMachExceptionRaiseStateIdentity
477 };
478 return std::set<mach_msg_id_t>(
479 &request_ids[0], &request_ids[arraysize(request_ids)]);
480 }
481
482 mach_msg_size_t MachExcServer::MachMessageServerRequestSize() {
483 return sizeof(__RequestUnion__mach_exc_subsystem);
484 }
485
486 mach_msg_size_t MachExcServer::MachMessageServerReplySize() {
487 return sizeof(__ReplyUnion__mach_exc_subsystem);
488 }
489
490 SimplifiedExcServer::SimplifiedExcServer(
491 SimplifiedExcServer::Interface* interface)
492 : ExcServer(this),
493 ExcServer::Interface(),
494 interface_(interface) {
495 }
496
497 kern_return_t SimplifiedExcServer::CatchExceptionRaise(
498 exception_handler_t exception_port,
499 thread_t thread,
500 task_t task,
501 exception_type_t exception,
502 const exception_data_type_t* code,
503 mach_msg_type_number_t code_count,
504 const mach_msg_trailer_t* trailer,
505 bool* destroy_request) {
506 thread_state_flavor_t flavor = THREAD_STATE_NONE;
507 mach_msg_type_number_t new_state_count = 0;
508 return interface_->CatchException(EXCEPTION_DEFAULT,
509 exception_port,
510 thread,
511 task,
512 exception,
513 code_count ? code : nullptr,
514 code_count,
515 &flavor,
516 nullptr,
517 0,
518 nullptr,
519 &new_state_count,
520 trailer,
521 destroy_request);
522 }
523
524 kern_return_t SimplifiedExcServer::CatchExceptionRaiseState(
525 exception_handler_t exception_port,
526 exception_type_t exception,
527 const exception_data_type_t* code,
528 mach_msg_type_number_t code_count,
529 thread_state_flavor_t* flavor,
530 const natural_t* old_state,
531 mach_msg_type_number_t old_state_count,
532 thread_state_t new_state,
533 mach_msg_type_number_t* new_state_count,
534 const mach_msg_trailer_t* trailer) {
535 bool destroy_complex_request = false;
536 return interface_->CatchException(EXCEPTION_STATE,
537 exception_port,
538 THREAD_NULL,
539 TASK_NULL,
540 exception,
541 code_count ? code : nullptr,
542 code_count,
543 flavor,
544 old_state_count ? old_state : nullptr,
545 old_state_count,
546 new_state_count ? new_state : nullptr,
547 new_state_count,
548 trailer,
549 &destroy_complex_request);
550 }
551
552 kern_return_t SimplifiedExcServer::CatchExceptionRaiseStateIdentity(
553 exception_handler_t exception_port,
554 thread_t thread,
555 task_t task,
556 exception_type_t exception,
557 const exception_data_type_t* code,
558 mach_msg_type_number_t code_count,
559 thread_state_flavor_t* flavor,
560 const natural_t* old_state,
561 mach_msg_type_number_t old_state_count,
562 thread_state_t new_state,
563 mach_msg_type_number_t* new_state_count,
564 const mach_msg_trailer_t* trailer,
565 bool* destroy_request) {
566 return interface_->CatchException(EXCEPTION_STATE_IDENTITY,
567 exception_port,
568 thread,
569 task,
570 exception,
571 code_count ? code : nullptr,
572 code_count,
573 flavor,
574 old_state_count ? old_state : nullptr,
575 old_state_count,
576 new_state_count ? new_state : nullptr,
577 new_state_count,
578 trailer,
579 destroy_request);
580 }
581
582 SimplifiedMachExcServer::SimplifiedMachExcServer(
583 SimplifiedMachExcServer::Interface* interface)
584 : MachExcServer(this),
585 MachExcServer::Interface(),
586 interface_(interface) {
587 }
588
589 kern_return_t SimplifiedMachExcServer::CatchMachExceptionRaise(
590 exception_handler_t exception_port,
591 thread_t thread,
592 task_t task,
593 exception_type_t exception,
594 const mach_exception_data_type_t* code,
595 mach_msg_type_number_t code_count,
596 const mach_msg_trailer_t* trailer,
597 bool* destroy_request) {
598 thread_state_flavor_t flavor = THREAD_STATE_NONE;
599 mach_msg_type_number_t new_state_count = 0;
600 return interface_->CatchMachException(
601 EXCEPTION_DEFAULT | MACH_EXCEPTION_CODES,
602 exception_port,
603 thread,
604 task,
605 exception,
606 code_count ? code : nullptr,
607 code_count,
608 &flavor,
609 nullptr,
610 0,
611 nullptr,
612 &new_state_count,
613 trailer,
614 destroy_request);
615 }
616
617 kern_return_t SimplifiedMachExcServer::CatchMachExceptionRaiseState(
618 exception_handler_t exception_port,
619 exception_type_t exception,
620 const mach_exception_data_type_t* code,
621 mach_msg_type_number_t code_count,
622 thread_state_flavor_t* flavor,
623 const natural_t* old_state,
624 mach_msg_type_number_t old_state_count,
625 thread_state_t new_state,
626 mach_msg_type_number_t* new_state_count,
627 const mach_msg_trailer_t* trailer) {
628 bool destroy_complex_request = false;
629 return interface_->CatchMachException(EXCEPTION_STATE | MACH_EXCEPTION_CODES,
630 exception_port,
631 THREAD_NULL,
632 TASK_NULL,
633 exception,
634 code_count ? code : nullptr,
635 code_count,
636 flavor,
637 old_state_count ? old_state : nullptr,
638 old_state_count,
639 new_state_count ? new_state : nullptr,
640 new_state_count,
641 trailer,
642 &destroy_complex_request);
643 }
644
645 kern_return_t SimplifiedMachExcServer::CatchMachExceptionRaiseStateIdentity(
646 exception_handler_t exception_port,
647 thread_t thread,
648 task_t task,
649 exception_type_t exception,
650 const mach_exception_data_type_t* code,
651 mach_msg_type_number_t code_count,
652 thread_state_flavor_t* flavor,
653 const natural_t* old_state,
654 mach_msg_type_number_t old_state_count,
655 thread_state_t new_state,
656 mach_msg_type_number_t* new_state_count,
657 const mach_msg_trailer_t* trailer,
658 bool* destroy_request) {
659 return interface_->CatchMachException(
660 EXCEPTION_STATE_IDENTITY | MACH_EXCEPTION_CODES,
661 exception_port,
662 thread,
663 task,
664 exception,
665 code_count ? code : nullptr,
666 code_count,
667 flavor,
668 old_state_count ? old_state : nullptr,
669 old_state_count,
670 new_state_count ? new_state : nullptr,
671 new_state_count,
672 trailer,
673 destroy_request);
674 }
675 736
676 } // namespace internal 737 } // namespace internal
677 738
678 UniversalMachExcServer::UniversalMachExcServer( 739 UniversalMachExcServer::UniversalMachExcServer(
679 UniversalMachExcServer::Interface* interface) 740 UniversalMachExcServer::Interface* interface)
680 : MachMessageServer::Interface(), 741 : MachMessageServer::Interface(),
681 internal::SimplifiedExcServer::Interface(), 742 impl_(new internal::UniversalMachExcServerImpl(interface)) {
682 internal::SimplifiedMachExcServer::Interface(), 743 }
683 exc_server_(this), 744
684 mach_exc_server_(this), 745 UniversalMachExcServer::~UniversalMachExcServer() {
685 interface_(interface) {
686 } 746 }
687 747
688 bool UniversalMachExcServer::MachMessageServerFunction( 748 bool UniversalMachExcServer::MachMessageServerFunction(
689 const mach_msg_header_t* in_header, 749 const mach_msg_header_t* in_header,
690 mach_msg_header_t* out_header, 750 mach_msg_header_t* out_header,
691 bool* destroy_complex_request) { 751 bool* destroy_complex_request) {
692 switch (in_header->msgh_id) { 752 return impl_->MachMessageServerFunction(
693 case kMachMessageIDMachExceptionRaise: 753 in_header, out_header, destroy_complex_request);
694 case kMachMessageIDMachExceptionRaiseState:
695 case kMachMessageIDMachExceptionRaiseStateIdentity:
696 return mach_exc_server_.MachMessageServerFunction(
697 in_header, out_header, destroy_complex_request);
698 case kMachMessageIDExceptionRaise:
699 case kMachMessageIDExceptionRaiseState:
700 case kMachMessageIDExceptionRaiseStateIdentity:
701 return exc_server_.MachMessageServerFunction(
702 in_header, out_header, destroy_complex_request);
703 }
704
705 // Do what the MIG-generated server routines do when they can’t dispatch a
706 // message.
707 PrepareMIGReplyFromRequest(in_header, out_header);
708 SetMIGReplyError(out_header, MIG_BAD_ID);
709 return false;
710 } 754 }
711 755
712 std::set<mach_msg_id_t> UniversalMachExcServer::MachMessageServerRequestIDs() { 756 std::set<mach_msg_id_t> UniversalMachExcServer::MachMessageServerRequestIDs() {
713 std::set<mach_msg_id_t> request_ids = 757 return impl_->MachMessageServerRequestIDs();
714 exc_server_.MachMessageServerRequestIDs();
715
716 std::set<mach_msg_id_t> mach_exc_request_ids =
717 mach_exc_server_.MachMessageServerRequestIDs();
718 request_ids.insert(mach_exc_request_ids.begin(), mach_exc_request_ids.end());
719
720 return request_ids;
721 } 758 }
722 759
723 mach_msg_size_t UniversalMachExcServer::MachMessageServerRequestSize() { 760 mach_msg_size_t UniversalMachExcServer::MachMessageServerRequestSize() {
724 return std::max(mach_exc_server_.MachMessageServerRequestSize(), 761 return impl_->MachMessageServerRequestSize();
725 exc_server_.MachMessageServerRequestSize());
726 } 762 }
727 763
728 mach_msg_size_t UniversalMachExcServer::MachMessageServerReplySize() { 764 mach_msg_size_t UniversalMachExcServer::MachMessageServerReplySize() {
729 return std::max(mach_exc_server_.MachMessageServerReplySize(), 765 return impl_->MachMessageServerReplySize();
730 exc_server_.MachMessageServerReplySize());
731 }
732
733 kern_return_t UniversalMachExcServer::CatchException(
734 exception_behavior_t behavior,
735 exception_handler_t exception_port,
736 thread_t thread,
737 task_t task,
738 exception_type_t exception,
739 const exception_data_type_t* code,
740 mach_msg_type_number_t code_count,
741 thread_state_flavor_t* flavor,
742 const natural_t* old_state,
743 mach_msg_type_number_t old_state_count,
744 thread_state_t new_state,
745 mach_msg_type_number_t* new_state_count,
746 const mach_msg_trailer_t* trailer,
747 bool* destroy_complex_request) {
748 std::vector<mach_exception_data_type_t> mach_codes;
749 mach_codes.reserve(code_count);
750 for (size_t index = 0; index < code_count; ++index) {
751 mach_codes.push_back(code[index]);
752 }
753
754 return interface_->CatchMachException(behavior,
755 exception_port,
756 thread,
757 task,
758 exception,
759 code_count ? &mach_codes[0] : nullptr,
760 code_count,
761 flavor,
762 old_state_count ? old_state : nullptr,
763 old_state_count,
764 new_state_count ? new_state : nullptr,
765 new_state_count,
766 trailer,
767 destroy_complex_request);
768 }
769
770 kern_return_t UniversalMachExcServer::CatchMachException(
771 exception_behavior_t behavior,
772 exception_handler_t exception_port,
773 thread_t thread,
774 task_t task,
775 exception_type_t exception,
776 const mach_exception_data_type_t* code,
777 mach_msg_type_number_t code_count,
778 thread_state_flavor_t* flavor,
779 const natural_t* old_state,
780 mach_msg_type_number_t old_state_count,
781 thread_state_t new_state,
782 mach_msg_type_number_t* new_state_count,
783 const mach_msg_trailer_t* trailer,
784 bool* destroy_complex_request) {
785 return interface_->CatchMachException(behavior,
786 exception_port,
787 thread,
788 task,
789 exception,
790 code_count ? code : nullptr,
791 code_count,
792 flavor,
793 old_state_count ? old_state : nullptr,
794 old_state_count,
795 new_state_count ? new_state : nullptr,
796 new_state_count,
797 trailer,
798 destroy_complex_request);
799 } 766 }
800 767
801 exception_type_t ExcCrashRecoverOriginalException( 768 exception_type_t ExcCrashRecoverOriginalException(
802 mach_exception_code_t code_0, 769 mach_exception_code_t code_0,
803 mach_exception_code_t* original_code_0, 770 mach_exception_code_t* original_code_0,
804 int* signal) { 771 int* signal) {
805 // 10.9.4 xnu-2422.110.17/bsd/kern/kern_exit.c proc_prepareexit() sets code[0] 772 // 10.9.4 xnu-2422.110.17/bsd/kern/kern_exit.c proc_prepareexit() sets code[0]
806 // based on the signal value, original exception type, and low 20 bits of the 773 // based on the signal value, original exception type, and low 20 bits of the
807 // original code[0] before calling xnu-2422.110.17/osfmk/kern/exception.c 774 // original code[0] before calling xnu-2422.110.17/osfmk/kern/exception.c
808 // task_exception_notify() to raise an EXC_CRASH. 775 // task_exception_notify() to raise an EXC_CRASH.
(...skipping 19 matching lines...) Expand all
828 kern_return_t ExcServerSuccessfulReturnValue(exception_behavior_t behavior, 795 kern_return_t ExcServerSuccessfulReturnValue(exception_behavior_t behavior,
829 bool set_thread_state) { 796 bool set_thread_state) {
830 if (!set_thread_state && ExceptionBehaviorHasState(behavior)) { 797 if (!set_thread_state && ExceptionBehaviorHasState(behavior)) {
831 return MACH_RCV_PORT_DIED; 798 return MACH_RCV_PORT_DIED;
832 } 799 }
833 800
834 return KERN_SUCCESS; 801 return KERN_SUCCESS;
835 } 802 }
836 803
837 } // namespace crashpad 804 } // namespace crashpad
OLDNEW
« no previous file with comments | « util/mach/exc_server_variants.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698