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 |