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 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
242 bool* destroy_complex_request) = 0; | 242 bool* destroy_complex_request) = 0; |
243 | 243 |
244 protected: | 244 protected: |
245 ~Interface() {} | 245 ~Interface() {} |
246 }; | 246 }; |
247 | 247 |
248 explicit SimplifiedExcServer(Interface* interface); | 248 explicit SimplifiedExcServer(Interface* interface); |
249 | 249 |
250 // ExcServer::Interface: | 250 // ExcServer::Interface: |
251 | 251 |
252 virtual kern_return_t CatchExceptionRaise( | 252 virtual kern_return_t CatchExceptionRaise(exception_handler_t exception_port, |
253 exception_handler_t exception_port, | 253 thread_t thread, |
254 thread_t thread, | 254 task_t task, |
255 task_t task, | 255 exception_type_t exception, |
256 exception_type_t exception, | 256 const exception_data_type_t* code, |
257 const exception_data_type_t* code, | 257 mach_msg_type_number_t code_count, |
258 mach_msg_type_number_t code_count, | 258 bool* destroy_request) override; |
259 bool* destroy_request) override; | |
260 virtual kern_return_t CatchExceptionRaiseState( | 259 virtual kern_return_t CatchExceptionRaiseState( |
261 exception_handler_t exception_port, | 260 exception_handler_t exception_port, |
262 exception_type_t exception, | 261 exception_type_t exception, |
263 const exception_data_type_t* code, | 262 const exception_data_type_t* code, |
264 mach_msg_type_number_t code_count, | 263 mach_msg_type_number_t code_count, |
265 thread_state_flavor_t* flavor, | 264 thread_state_flavor_t* flavor, |
266 const natural_t* old_state, | 265 const natural_t* old_state, |
267 mach_msg_type_number_t old_state_count, | 266 mach_msg_type_number_t old_state_count, |
268 thread_state_t new_state, | 267 thread_state_t new_state, |
269 mach_msg_type_number_t* new_state_count) override; | 268 mach_msg_type_number_t* new_state_count) override; |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
404 virtual bool MachMessageServerFunction( | 403 virtual bool MachMessageServerFunction( |
405 const mach_msg_header_t* in_header, | 404 const mach_msg_header_t* in_header, |
406 mach_msg_header_t* out_header, | 405 mach_msg_header_t* out_header, |
407 bool* destroy_complex_request) override; | 406 bool* destroy_complex_request) override; |
408 | 407 |
409 virtual mach_msg_size_t MachMessageServerRequestSize() override; | 408 virtual mach_msg_size_t MachMessageServerRequestSize() override; |
410 virtual mach_msg_size_t MachMessageServerReplySize() override; | 409 virtual mach_msg_size_t MachMessageServerReplySize() override; |
411 | 410 |
412 // internal::SimplifiedExcServer::Interface: | 411 // internal::SimplifiedExcServer::Interface: |
413 | 412 |
414 virtual kern_return_t CatchException( | 413 virtual kern_return_t CatchException(exception_behavior_t behavior, |
415 exception_behavior_t behavior, | 414 exception_handler_t exception_port, |
416 exception_handler_t exception_port, | 415 thread_t thread, |
417 thread_t thread, | 416 task_t task, |
418 task_t task, | 417 exception_type_t exception, |
419 exception_type_t exception, | 418 const exception_data_type_t* code, |
420 const exception_data_type_t* code, | 419 mach_msg_type_number_t code_count, |
421 mach_msg_type_number_t code_count, | 420 thread_state_flavor_t* flavor, |
422 thread_state_flavor_t* flavor, | 421 const natural_t* old_state, |
423 const natural_t* old_state, | 422 mach_msg_type_number_t old_state_count, |
424 mach_msg_type_number_t old_state_count, | 423 thread_state_t new_state, |
425 thread_state_t new_state, | 424 mach_msg_type_number_t* new_state_count, |
426 mach_msg_type_number_t* new_state_count, | 425 bool* destroy_complex_request) override; |
427 bool* destroy_complex_request) override; | |
428 | 426 |
429 private: | 427 private: |
430 internal::SimplifiedExcServer exc_server_; | 428 internal::SimplifiedExcServer exc_server_; |
431 internal::SimplifiedMachExcServer mach_exc_server_; | 429 internal::SimplifiedMachExcServer mach_exc_server_; |
432 }; | 430 }; |
433 | 431 |
432 //! \brief Computes an approriate successful return value for an exception | |
433 //! handler function. | |
434 //! | |
435 //! For exception handlers that respond to state-carrying behaviors, when the | |
436 //! handler is called by the kernel (as it is normally), the kernel will attempt | |
437 //! to set a new thread state when the exception handler returns successfully. | |
438 //! Other code that mimics the kernel’s exception-delivery semantics may | |
439 //! implement the same or similar behavior. In some situations, it is | |
440 //! undesirable to set a new thread state. If the exception handler were to | |
441 //! return unsuccessfully, however, the kernel would continue searching for an | |
442 //! exception handler at a wider (task or host) scope. This may also be | |
Robert Sesek
2014/09/17 15:29:38
Do you ever want to let the kernel search for a wi
Mark Mentovai
2014/09/17 15:35:38
rsesek wrote:
| |
443 //! undesirable. | |
444 //! | |
445 //! If such exception handlers return `MACH_RCV_PORT_DIED`, the kernel will not | |
446 //! set a new thread state and will also not search for another exception | |
447 //! handler. See 10.9.4 `xnu-2422.110.17/osfmk/kern/exception.c`. | |
448 //! `exception_deliver()` will only set a new thread state if the handler’s | |
449 //! return code was `MACH_MSG_SUCCESS` (a synonym for `KERN_SUCCESS`), and | |
450 //! subsequently, `exception_triage()` will not search for a new handler if the | |
451 //! handler’s return code was `KERN_SUCCESS` or `MACH_RCV_PORT_DIED`. | |
452 //! | |
453 //! This function allows exception handlers to compute an appropriate return | |
454 //! code to influence their caller (the kernel) in the desired way with respect | |
455 //! to setting a new thread state while suppressing the caller’s subsequent | |
456 //! search for other exception handlers. An exception handler should return the | |
457 //! value returned by this function. | |
458 //! | |
459 //! This function is useful even for `EXC_CRASH` handlers, where returning | |
460 //! `KERN_SUCCESS` and allowing the kernel to set a new thread state has been | |
461 //! observed to cause a perceptible and unnecessary waste of time. The victim | |
462 //! task in an `EXC_CRASH` handler is already being terminated and is no longer | |
463 //! schedulable, so there is no point in setting the states of any of its | |
464 //! threads. | |
465 //! | |
466 //! \param[in] behavior The behavior of the exception handler as invoked. This | |
467 //! may be taken directly from the \a behavior parameter of | |
468 //! internal::SimplifiedExcServer::Interface::CatchException(), for example. | |
469 //! \param[in] set_thread_state `true` if the handler would like its caller to | |
470 //! set the new thread state using the \a flavor, \a new_state, and \a | |
471 //! new_state_count out parameters. This can only happen when \a behavior is | |
472 //! a state-carrying behavior. | |
473 //! | |
474 //! \return `KERN_SUCCESS` or `MACH_RCV_PORT_DIED`. `KERN_SUCCESS` is used when | |
475 //! \a behavior is not a state-carrying behavior, or when it is a | |
476 //! state-carrying behavior and \a set_thread_state is `true`. | |
477 //! `MACH_RCV_PORT_DIED` is used when \a behavior is a state-carrying | |
478 //! behavior and \a set_thread_state is `false`. | |
479 kern_return_t ExcServerSuccessfulReturnValue(exception_behavior_t behavior, | |
480 bool set_thread_state); | |
481 | |
434 } // namespace crashpad | 482 } // namespace crashpad |
435 | 483 |
436 #endif // CRASHPAD_UTIL_MACH_EXC_SERVER_VARIANTS_H_ | 484 #endif // CRASHPAD_UTIL_MACH_EXC_SERVER_VARIANTS_H_ |
OLD | NEW |