| 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
|
| +//! 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_
|
|
|