Chromium Code Reviews| Index: util/mach/exc_server_variants.h |
| diff --git a/util/mach/exc_server_variants.h b/util/mach/exc_server_variants.h |
| index 81651cec7a5f6451a1a22cf8cf50883f56d9edb2..d605869a4f4ca15781fc434534ef0d55f3add90e 100644 |
| --- a/util/mach/exc_server_variants.h |
| +++ b/util/mach/exc_server_variants.h |
| @@ -249,14 +249,13 @@ class SimplifiedExcServer : public ExcServer, public ExcServer::Interface { |
| // ExcServer::Interface: |
| - virtual kern_return_t CatchExceptionRaise( |
| - exception_handler_t exception_port, |
| - thread_t thread, |
| - task_t task, |
| - exception_type_t exception, |
| - const exception_data_type_t* code, |
| - mach_msg_type_number_t code_count, |
| - bool* destroy_request) override; |
| + virtual kern_return_t CatchExceptionRaise(exception_handler_t exception_port, |
| + thread_t thread, |
| + task_t task, |
| + exception_type_t exception, |
| + const exception_data_type_t* code, |
| + mach_msg_type_number_t code_count, |
| + bool* destroy_request) override; |
| virtual kern_return_t CatchExceptionRaiseState( |
| exception_handler_t exception_port, |
| exception_type_t exception, |
| @@ -411,26 +410,75 @@ class UniversalMachExcServer |
| // internal::SimplifiedExcServer::Interface: |
| - virtual kern_return_t CatchException( |
| - exception_behavior_t behavior, |
| - exception_handler_t exception_port, |
| - thread_t thread, |
| - task_t task, |
| - exception_type_t exception, |
| - const exception_data_type_t* code, |
| - mach_msg_type_number_t code_count, |
| - thread_state_flavor_t* flavor, |
| - const natural_t* old_state, |
| - mach_msg_type_number_t old_state_count, |
| - thread_state_t new_state, |
| - mach_msg_type_number_t* new_state_count, |
| - bool* destroy_complex_request) override; |
| + virtual kern_return_t CatchException(exception_behavior_t behavior, |
| + exception_handler_t exception_port, |
| + thread_t thread, |
| + task_t task, |
| + exception_type_t exception, |
| + const exception_data_type_t* code, |
| + mach_msg_type_number_t code_count, |
| + thread_state_flavor_t* flavor, |
| + const natural_t* old_state, |
| + mach_msg_type_number_t old_state_count, |
| + thread_state_t new_state, |
| + mach_msg_type_number_t* new_state_count, |
| + bool* destroy_complex_request) override; |
| private: |
| internal::SimplifiedExcServer exc_server_; |
| internal::SimplifiedMachExcServer mach_exc_server_; |
| }; |
| +//! \brief Computes an approriate successful return value for an exception |
| +//! handler function. |
| +//! |
| +//! For exception handlers that respond to state-carrying behaviors, when the |
| +//! handler is called by the kernel (as it is normally), the kernel will attempt |
| +//! to set a new thread state when the exception handler returns successfully. |
| +//! Other code that mimics the kernel’s exception-delivery semantics may |
| +//! implement the same or similar behavior. In some situations, it is |
| +//! undesirable to set a new thread state. If the exception handler were to |
| +//! return unsuccessfully, however, the kernel would continue searching for an |
| +//! 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:
|
| +//! undesirable. |
| +//! |
| +//! If such exception handlers return `MACH_RCV_PORT_DIED`, the kernel will not |
| +//! set a new thread state and will also not search for another exception |
| +//! handler. See 10.9.4 `xnu-2422.110.17/osfmk/kern/exception.c`. |
| +//! `exception_deliver()` will only set a new thread state if the handler’s |
| +//! return code was `MACH_MSG_SUCCESS` (a synonym for `KERN_SUCCESS`), and |
| +//! subsequently, `exception_triage()` will not search for a new handler if the |
| +//! handler’s return code was `KERN_SUCCESS` or `MACH_RCV_PORT_DIED`. |
| +//! |
| +//! This function allows exception handlers to compute an appropriate return |
| +//! code to influence their caller (the kernel) in the desired way with respect |
| +//! to setting a new thread state while suppressing the caller’s subsequent |
| +//! search for other exception handlers. An exception handler should return the |
| +//! value returned by this function. |
| +//! |
| +//! This function is useful even for `EXC_CRASH` handlers, where returning |
| +//! `KERN_SUCCESS` and allowing the kernel to set a new thread state has been |
| +//! observed to cause a perceptible and unnecessary waste of time. The victim |
| +//! task in an `EXC_CRASH` handler is already being terminated and is no longer |
| +//! schedulable, so there is no point in setting the states of any of its |
| +//! threads. |
| +//! |
| +//! \param[in] behavior The behavior of the exception handler as invoked. This |
| +//! may be taken directly from the \a behavior parameter of |
| +//! internal::SimplifiedExcServer::Interface::CatchException(), for example. |
| +//! \param[in] set_thread_state `true` if the handler would like its caller to |
| +//! set the new thread state using the \a flavor, \a new_state, and \a |
| +//! new_state_count out parameters. This can only happen when \a behavior is |
| +//! a state-carrying behavior. |
| +//! |
| +//! \return `KERN_SUCCESS` or `MACH_RCV_PORT_DIED`. `KERN_SUCCESS` is used when |
| +//! \a behavior is not a state-carrying behavior, or when it is a |
| +//! state-carrying behavior and \a set_thread_state is `true`. |
| +//! `MACH_RCV_PORT_DIED` is used when \a behavior is a state-carrying |
| +//! behavior and \a set_thread_state is `false`. |
| +kern_return_t ExcServerSuccessfulReturnValue(exception_behavior_t behavior, |
| + bool set_thread_state); |
| + |
| } // namespace crashpad |
| #endif // CRASHPAD_UTIL_MACH_EXC_SERVER_VARIANTS_H_ |