Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2014 The Crashpad Authors. All rights reserved. | |
| 2 // | |
| 3 // Licensed under the Apache License, Version 2.0 (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 | |
| 6 // | |
| 7 // http://www.apache.org/licenses/LICENSE-2.0 | |
| 8 // | |
| 9 // Unless required by applicable law or agreed to in writing, software | |
| 10 // distributed under the License is distributed on an "AS IS" BASIS, | |
| 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| 12 // See the License for the specific language governing permissions and | |
| 13 // limitations under the License. | |
| 14 | |
| 15 #ifndef CRASHPAD_UTIL_MACH_EXC_SERVER_VARIANTS_H_ | |
| 16 #define CRASHPAD_UTIL_MACH_EXC_SERVER_VARIANTS_H_ | |
| 17 | |
| 18 #include <mach/mach.h> | |
| 19 | |
| 20 #include "util/mach/mach_message_server.h" | |
| 21 | |
| 22 namespace crashpad { | |
| 23 | |
| 24 // Routines to provide a single unified front-end to the interfaces in | |
| 25 // <mach/exc.defs> and <mach/mach_exc.defs>. The two interfaces are identical, | |
| 26 // except that the latter allows for 64-bit exception codes, and is requested by | |
| 27 // setting the MACH_EXCEPTION_CODES behavior bit associated with an exception | |
| 28 // port. | |
| 29 | |
| 30 //! \brief A server interface for the `exc` Mach subsystem. | |
| 31 class ExcServer : public MachMessageServer::Interface { | |
| 32 public: | |
| 33 //! \brief An interface that the different request messages that are a part of | |
| 34 //! the `exc` Mach subsystem can be dispatched to. | |
| 35 class Interface { | |
| 36 public: | |
| 37 //! \brief Handles exceptions raised by `exception_raise()`. | |
| 38 //! | |
| 39 //! This behaves equivalently to a `catch_exception_raise()` function used | |
| 40 //! with `exc_server()`. | |
| 41 //! | |
| 42 //! \param[out] destroy_request `true` if the request message is to be | |
| 43 //! destroyed even when this method returns success. See | |
| 44 //! MachMessageServer::Interface. | |
| 45 virtual kern_return_t CatchExceptionRaise( | |
| 46 exception_handler_t exception_port, | |
| 47 thread_t thread, | |
| 48 task_t task, | |
| 49 exception_type_t exception, | |
| 50 const exception_data_type_t* code, | |
| 51 mach_msg_type_number_t code_count, | |
| 52 bool* destroy_request) = 0; | |
| 53 | |
| 54 //! \brief Handles exceptions raised by `exception_raise_state()`. | |
| 55 //! | |
| 56 //! This behaves equivalently to a `catch_exception_raise_state()` function | |
| 57 //! used with `exc_server()`. | |
| 58 virtual kern_return_t CatchExceptionRaiseState( | |
| 59 exception_handler_t exception_port, | |
| 60 exception_type_t exception, | |
| 61 const exception_data_type_t* code, | |
| 62 mach_msg_type_number_t code_count, | |
| 63 thread_state_flavor_t* flavor, | |
| 64 const natural_t* old_state, | |
| 65 mach_msg_type_number_t old_state_count, | |
| 66 thread_state_t new_state, | |
| 67 mach_msg_type_number_t* new_state_count) = 0; | |
|
Robert Sesek
2014/09/10 16:44:41
No destroy_request?
Mark Mentovai
2014/09/10 20:12:56
rsesek wrote:
| |
| 68 | |
| 69 //! \brief Handles exceptions raised by `exception_raise_state_identity()`. | |
| 70 //! | |
| 71 //! This behaves equivalently to a `catch_exception_raise_state_identity()` | |
| 72 //! function used with `exc_server()`. | |
| 73 //! | |
| 74 //! \param[out] destroy_request `true` if the request message is to be | |
| 75 //! destroyed even when this method returns success. See | |
| 76 //! MachMessageServer::Interface. | |
| 77 virtual kern_return_t CatchExceptionRaiseStateIdentity( | |
| 78 exception_handler_t exception_port, | |
| 79 thread_t thread, | |
| 80 task_t task, | |
| 81 exception_type_t exception, | |
| 82 const exception_data_type_t* code, | |
| 83 mach_msg_type_number_t code_count, | |
| 84 thread_state_flavor_t* flavor, | |
| 85 const natural_t* old_state, | |
| 86 mach_msg_type_number_t old_state_count, | |
| 87 thread_state_t new_state, | |
| 88 mach_msg_type_number_t* new_state_count, | |
| 89 bool* destroy_request) = 0; | |
| 90 | |
| 91 protected: | |
| 92 ~Interface() {} | |
| 93 }; | |
| 94 | |
| 95 explicit ExcServer(Interface* interface); | |
| 96 | |
| 97 // MachMessageServer::Interface: | |
| 98 | |
| 99 virtual bool MachMessageServerFunction( | |
| 100 mach_msg_header_t* in_header, | |
| 101 mach_msg_header_t* out_header, | |
| 102 bool* destroy_complex_request) override; | |
| 103 | |
| 104 virtual mach_msg_size_t MachMessageServerRequestSize() override; | |
| 105 virtual mach_msg_size_t MachMessageServerReplySize() override; | |
| 106 | |
| 107 private: | |
| 108 Interface* interface_; // weak | |
| 109 }; | |
| 110 | |
| 111 //! \brief A server interface for the `mach_exc` Mach subsystem. | |
| 112 class MachExcServer : public MachMessageServer::Interface { | |
| 113 public: | |
| 114 //! \brief An interface that the different request messages that are a part of | |
| 115 //! the `mach_exc` Mach subsystem can be dispatched to. | |
| 116 class Interface { | |
| 117 public: | |
| 118 //! \brief Handles exceptions raised by `mach_exception_raise()`. | |
| 119 //! | |
| 120 //! This behaves equivalently to a `catch_mach_exception_raise()` function | |
| 121 //! used with `mach_exc_server()`. | |
| 122 //! | |
| 123 //! \param[out] destroy_request `true` if the request message is to be | |
| 124 //! destroyed even when this method returns success. See | |
| 125 //! MachMessageServer::Interface. | |
| 126 virtual kern_return_t CatchMachExceptionRaise( | |
| 127 exception_handler_t exception_port, | |
| 128 thread_t thread, | |
| 129 task_t task, | |
| 130 exception_type_t exception, | |
| 131 const mach_exception_data_type_t* code, | |
| 132 mach_msg_type_number_t code_count, | |
| 133 bool* destroy_request) = 0; | |
| 134 | |
| 135 //! \brief Handles exceptions raised by `mach_exception_raise_state()`. | |
| 136 //! | |
| 137 //! This behaves equivalently to a `catch_mach_exception_raise_state()` | |
| 138 //! function used with `mach_exc_server()`. | |
| 139 virtual kern_return_t CatchMachExceptionRaiseState( | |
| 140 exception_handler_t exception_port, | |
| 141 exception_type_t exception, | |
| 142 const mach_exception_data_type_t* code, | |
| 143 mach_msg_type_number_t code_count, | |
| 144 thread_state_flavor_t* flavor, | |
| 145 const natural_t* old_state, | |
| 146 mach_msg_type_number_t old_state_count, | |
| 147 thread_state_t new_state, | |
| 148 mach_msg_type_number_t* new_state_count) = 0; | |
| 149 | |
| 150 //! \brief Handles exceptions raised by | |
| 151 //! `mach_exception_raise_state_identity()`. | |
| 152 //! | |
| 153 //! This behaves equivalently to a | |
| 154 //! `catch_mach_exception_raise_state_identity()` function used with | |
| 155 //! `mach_exc_server()`. | |
| 156 //! | |
| 157 //! \param[out] destroy_request `true` if the request message is to be | |
| 158 //! destroyed even when this method returns success. See | |
| 159 //! MachMessageServer::Interface. | |
| 160 virtual kern_return_t CatchMachExceptionRaiseStateIdentity( | |
| 161 exception_handler_t exception_port, | |
| 162 thread_t thread, | |
| 163 task_t task, | |
| 164 exception_type_t exception, | |
| 165 const mach_exception_data_type_t* code, | |
| 166 mach_msg_type_number_t code_count, | |
| 167 thread_state_flavor_t* flavor, | |
| 168 const natural_t* old_state, | |
| 169 mach_msg_type_number_t old_state_count, | |
| 170 thread_state_t new_state, | |
| 171 mach_msg_type_number_t* new_state_count, | |
| 172 bool* destroy_request) = 0; | |
| 173 | |
| 174 protected: | |
| 175 ~Interface() {} | |
| 176 }; | |
| 177 | |
| 178 explicit MachExcServer(Interface* interface); | |
| 179 | |
| 180 // MachMessageServer::Interface: | |
| 181 | |
| 182 virtual bool MachMessageServerFunction( | |
| 183 mach_msg_header_t* in_header, | |
| 184 mach_msg_header_t* out_header, | |
| 185 bool* destroy_complex_request) override; | |
| 186 | |
| 187 virtual mach_msg_size_t MachMessageServerRequestSize() override; | |
| 188 virtual mach_msg_size_t MachMessageServerReplySize() override; | |
| 189 | |
| 190 private: | |
| 191 Interface* interface_; // weak | |
| 192 }; | |
| 193 | |
| 194 //! \brief A server interface for the `exc` Mach subsystem, simplified to have | |
| 195 //! only a single interface method needing implementation. | |
| 196 class SimplifiedExcServer : public ExcServer, public ExcServer::Interface { | |
| 197 public: | |
| 198 //! \brief An interface that the different request messages that are a part of | |
| 199 //! the `exc` Mach subsystem can be dispatched to. | |
| 200 class Interface { | |
| 201 public: | |
| 202 //! \brief Handles exceptions raised by `exception_raise()`, | |
| 203 //! `exception_raise_state()`, and `exception_raise_state_identity()`. | |
| 204 //! | |
| 205 //! For convenience in implementation, these different “behaviors” of | |
| 206 //! exception messages are all mapped to a single interface method. The | |
| 207 //! exception’s original “behavior” is specified in the \a behavior | |
| 208 //! parameter. Only parameters that were supplied in the request message | |
| 209 //! are populated, other parameters are set to reasonable default values. | |
| 210 //! | |
| 211 //! The meanings of most parameters are identical to that of | |
| 212 //! ExcServer::Interface::CatchExceptionRaiseStateIdentity(). | |
| 213 //! | |
| 214 //! \param[in] behavior `EXCEPTION_DEFAULT`, `EXCEPTION_STATE`, or | |
| 215 //! `EXCEPTION_STATE_IDENTITY`, identifying which exception request | |
| 216 //! message was processed and thus which other parameters are valid. | |
| 217 virtual kern_return_t CatchException( | |
| 218 exception_behavior_t behavior, | |
| 219 exception_handler_t exception_port, | |
| 220 thread_t thread, | |
| 221 task_t task, | |
| 222 exception_type_t exception, | |
| 223 const exception_data_type_t* code, | |
| 224 mach_msg_type_number_t code_count, | |
| 225 thread_state_flavor_t* flavor, | |
| 226 const natural_t* old_state, | |
| 227 mach_msg_type_number_t old_state_count, | |
| 228 thread_state_t new_state, | |
| 229 mach_msg_type_number_t* new_state_count, | |
| 230 bool* destroy_complex_request) = 0; | |
| 231 | |
| 232 protected: | |
| 233 ~Interface() {} | |
| 234 }; | |
| 235 | |
| 236 explicit SimplifiedExcServer(Interface* interface); | |
| 237 | |
| 238 // ExcServer::Interface: | |
| 239 | |
| 240 virtual kern_return_t CatchExceptionRaise( | |
| 241 exception_handler_t exception_port, | |
| 242 thread_t thread, | |
| 243 task_t task, | |
| 244 exception_type_t exception, | |
| 245 const exception_data_type_t* code, | |
| 246 mach_msg_type_number_t code_count, | |
| 247 bool* destroy_request) override; | |
| 248 virtual kern_return_t CatchExceptionRaiseState( | |
| 249 exception_handler_t exception_port, | |
| 250 exception_type_t exception, | |
| 251 const exception_data_type_t* code, | |
| 252 mach_msg_type_number_t code_count, | |
| 253 thread_state_flavor_t* flavor, | |
| 254 const natural_t* old_state, | |
| 255 mach_msg_type_number_t old_state_count, | |
| 256 thread_state_t new_state, | |
| 257 mach_msg_type_number_t* new_state_count) override; | |
| 258 virtual kern_return_t CatchExceptionRaiseStateIdentity( | |
| 259 exception_handler_t exception_port, | |
| 260 thread_t thread, | |
| 261 task_t task, | |
| 262 exception_type_t exception, | |
| 263 const exception_data_type_t* code, | |
| 264 mach_msg_type_number_t code_count, | |
| 265 thread_state_flavor_t* flavor, | |
| 266 const natural_t* old_state, | |
| 267 mach_msg_type_number_t old_state_count, | |
| 268 thread_state_t new_state, | |
| 269 mach_msg_type_number_t* new_state_count, | |
| 270 bool* destroy_request) override; | |
| 271 | |
| 272 private: | |
| 273 Interface* interface_; // weak | |
| 274 }; | |
| 275 | |
| 276 //! \brief A server interface for the `mach_exc` Mach subsystem, simplified to | |
| 277 //! have only a single interface method needing implementation. | |
| 278 class SimplifiedMachExcServer : public MachExcServer, | |
|
Robert Sesek
2014/09/10 16:44:41
Do you really need to present all of these interfa
Mark Mentovai
2014/09/10 20:12:56
rsesek wrote:
| |
| 279 public MachExcServer::Interface { | |
| 280 public: | |
| 281 //! \brief An interface that the different request messages that are a part of | |
| 282 //! the `mach_exc` Mach subsystem can be dispatched to. | |
| 283 class Interface { | |
| 284 public: | |
| 285 //! \brief Handles exceptions raised by `mach_exception_raise()`, | |
| 286 //! `mach_exception_raise_state()`, and | |
| 287 //! `mach_exception_raise_state_identity()`. | |
| 288 //! | |
| 289 //! When used with UniversalMachExcServer, this also handles exceptions | |
| 290 //! raised by `exception_raise()`, `exception_raise_state()`, and | |
| 291 //! `exception_raise_state_identity()`. | |
| 292 //! | |
| 293 //! For convenience in implementation, these different “behaviors” of | |
| 294 //! exception messages are all mapped to a single interface method. The | |
| 295 //! exception’s original “behavior” is specified in the \a behavior | |
| 296 //! parameter. Only parameters that were supplied in the request message | |
| 297 //! are populated, other parameters are set to reasonable default values. | |
| 298 //! | |
| 299 //! The meanings of most parameters are identical to that of | |
| 300 //! MachExcServer::Interface::CatchMachExceptionRaiseStateIdentity(). | |
| 301 //! | |
| 302 //! \param[in] behavior `MACH_EXCEPTION_CODES | EXCEPTION_DEFAULT`, | |
| 303 //! `MACH_EXCEPTION_CODES | EXCEPTION_STATE`, or | |
| 304 //! `MACH_EXCEPTION_CODES | EXCEPTION_STATE_IDENTITY`, identifying which | |
| 305 //! exception request message was processed and thus which other | |
| 306 //! parameters are valid. When used with UniversalMachExcServer, \a | |
| 307 //! behavior can also be `EXCEPTION_DEFAULT`, `EXCEPTION_STATE`, or | |
| 308 //! `EXCEPTION_STATE_IDENTITY`. | |
| 309 virtual kern_return_t CatchMachException( | |
| 310 exception_behavior_t behavior, | |
| 311 exception_handler_t exception_port, | |
| 312 thread_t thread, | |
| 313 task_t task, | |
| 314 exception_type_t exception, | |
| 315 const mach_exception_data_type_t* code, | |
| 316 mach_msg_type_number_t code_count, | |
| 317 thread_state_flavor_t* flavor, | |
| 318 const natural_t* old_state, | |
| 319 mach_msg_type_number_t old_state_count, | |
| 320 thread_state_t new_state, | |
| 321 mach_msg_type_number_t* new_state_count, | |
| 322 bool* destroy_complex_request) = 0; | |
| 323 | |
| 324 protected: | |
| 325 ~Interface() {} | |
| 326 }; | |
| 327 | |
| 328 explicit SimplifiedMachExcServer(Interface* interface); | |
| 329 | |
| 330 // MachExcServer::Interface: | |
| 331 | |
| 332 virtual kern_return_t CatchMachExceptionRaise( | |
| 333 exception_handler_t exception_port, | |
| 334 thread_t thread, | |
| 335 task_t task, | |
| 336 exception_type_t exception, | |
| 337 const mach_exception_data_type_t* code, | |
| 338 mach_msg_type_number_t code_count, | |
| 339 bool* destroy_request) override; | |
| 340 virtual kern_return_t CatchMachExceptionRaiseState( | |
| 341 exception_handler_t exception_port, | |
| 342 exception_type_t exception, | |
| 343 const mach_exception_data_type_t* code, | |
| 344 mach_msg_type_number_t code_count, | |
| 345 thread_state_flavor_t* flavor, | |
| 346 const natural_t* old_state, | |
| 347 mach_msg_type_number_t old_state_count, | |
| 348 thread_state_t new_state, | |
| 349 mach_msg_type_number_t* new_state_count) override; | |
| 350 virtual kern_return_t CatchMachExceptionRaiseStateIdentity( | |
| 351 exception_handler_t exception_port, | |
| 352 thread_t thread, | |
| 353 task_t task, | |
| 354 exception_type_t exception, | |
| 355 const mach_exception_data_type_t* code, | |
| 356 mach_msg_type_number_t code_count, | |
| 357 thread_state_flavor_t* flavor, | |
| 358 const natural_t* old_state, | |
| 359 mach_msg_type_number_t old_state_count, | |
| 360 thread_state_t new_state, | |
| 361 mach_msg_type_number_t* new_state_count, | |
| 362 bool* destroy_request) override; | |
| 363 | |
| 364 private: | |
| 365 Interface* interface_; // weak | |
| 366 }; | |
| 367 | |
| 368 //! \brief A server interface for the `exc` and `mach_exc` Mach subsystems, | |
| 369 //! unified to handle exceptions delivered to either subsystem, and | |
| 370 //! simplified to have only a single interface method needing | |
| 371 //! implementation. | |
| 372 //! | |
| 373 //! UniversalMachExcServer operates by translating messages received in the | |
| 374 //! `exc` subsystem to a variant that is compatible with the `mach_exc` | |
| 375 //! subsystem. This involves changing the format of \a code, the exception code | |
| 376 //! field, from `exception_data_type_t` to `mach_exception_data_type_t`. | |
| 377 //! This is achieved by implementing SimplifiedExcServer::Interface and having | |
| 378 //! it forward translated messages to SimplifiedMachExcServer::Interface, which | |
| 379 //! is left unimplemented here so that users of this class can provide their own | |
| 380 //! implementations. | |
| 381 class UniversalMachExcServer : public MachMessageServer::Interface, | |
| 382 public SimplifiedExcServer::Interface, | |
| 383 public SimplifiedMachExcServer::Interface { | |
| 384 public: | |
| 385 UniversalMachExcServer(); | |
| 386 | |
| 387 // MachMessageServer::Interface: | |
| 388 | |
| 389 virtual bool MachMessageServerFunction( | |
| 390 mach_msg_header_t* in_header, | |
| 391 mach_msg_header_t* out_header, | |
| 392 bool* destroy_complex_request) override; | |
| 393 | |
| 394 virtual mach_msg_size_t MachMessageServerRequestSize() override; | |
| 395 virtual mach_msg_size_t MachMessageServerReplySize() override; | |
| 396 | |
| 397 // SimplifiedExcServer::Interface: | |
| 398 | |
| 399 virtual kern_return_t CatchException( | |
| 400 exception_behavior_t behavior, | |
| 401 exception_handler_t exception_port, | |
| 402 thread_t thread, | |
| 403 task_t task, | |
| 404 exception_type_t exception, | |
| 405 const exception_data_type_t* code, | |
| 406 mach_msg_type_number_t code_count, | |
| 407 thread_state_flavor_t* flavor, | |
| 408 const natural_t* old_state, | |
| 409 mach_msg_type_number_t old_state_count, | |
| 410 thread_state_t new_state, | |
| 411 mach_msg_type_number_t* new_state_count, | |
| 412 bool* destroy_complex_request) override; | |
| 413 | |
| 414 private: | |
| 415 SimplifiedExcServer exc_server_; | |
| 416 SimplifiedMachExcServer mach_exc_server_; | |
| 417 }; | |
| 418 | |
| 419 } // namespace crashpad | |
| 420 | |
| 421 #endif // CRASHPAD_UTIL_MACH_EXC_SERVER_VARIANTS_H_ | |
| OLD | NEW |