| 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 |
| 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 |