Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(71)

Side by Side Diff: util/mach/exc_server_variants.h

Issue 545053003: Add exc_server_variants including UniversalMachExcServer and its test (Closed) Base URL: https://chromium.googlesource.com/crashpad/crashpad@master
Patch Set: Address review feedback Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « util/mach/bootstrap_test.cc ('k') | util/mach/exc_server_variants.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(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 namespace internal {
31
32 //! \brief A server interface for the `exc` Mach subsystem.
33 class ExcServer : public MachMessageServer::Interface {
34 public:
35 //! \brief An interface that the different request messages that are a part of
36 //! the `exc` Mach subsystem can be dispatched to.
37 class Interface {
38 public:
39 //! \brief Handles exceptions raised by `exception_raise()`.
40 //!
41 //! This behaves equivalently to a `catch_exception_raise()` function used
42 //! with `exc_server()`.
43 //!
44 //! \param[out] destroy_request `true` if the request message is to be
45 //! destroyed even when this method returns success. See
46 //! MachMessageServer::Interface.
47 virtual kern_return_t CatchExceptionRaise(
48 exception_handler_t exception_port,
49 thread_t thread,
50 task_t task,
51 exception_type_t exception,
52 const exception_data_type_t* code,
53 mach_msg_type_number_t code_count,
54 bool* destroy_request) = 0;
55
56 //! \brief Handles exceptions raised by `exception_raise_state()`.
57 //!
58 //! This behaves equivalently to a `catch_exception_raise_state()` function
59 //! used with `exc_server()`.
60 //!
61 //! There is no \a destroy_request parameter because, unlike
62 //! CatchExceptionRaise() and CatchExceptionRaiseStateIdentity(), the
63 //! request message is not complex (it does not carry the \a thread or \a
64 //! task port rights) and thus there is nothing to destroy.
65 virtual kern_return_t CatchExceptionRaiseState(
66 exception_handler_t exception_port,
67 exception_type_t exception,
68 const exception_data_type_t* code,
69 mach_msg_type_number_t code_count,
70 thread_state_flavor_t* flavor,
71 const natural_t* old_state,
72 mach_msg_type_number_t old_state_count,
73 thread_state_t new_state,
74 mach_msg_type_number_t* new_state_count) = 0;
75
76 //! \brief Handles exceptions raised by `exception_raise_state_identity()`.
77 //!
78 //! This behaves equivalently to a `catch_exception_raise_state_identity()`
79 //! function used with `exc_server()`.
80 //!
81 //! \param[out] destroy_request `true` if the request message is to be
82 //! destroyed even when this method returns success. See
83 //! MachMessageServer::Interface.
84 virtual kern_return_t CatchExceptionRaiseStateIdentity(
85 exception_handler_t exception_port,
86 thread_t thread,
87 task_t task,
88 exception_type_t exception,
89 const exception_data_type_t* code,
90 mach_msg_type_number_t code_count,
91 thread_state_flavor_t* flavor,
92 const natural_t* old_state,
93 mach_msg_type_number_t old_state_count,
94 thread_state_t new_state,
95 mach_msg_type_number_t* new_state_count,
96 bool* destroy_request) = 0;
97
98 protected:
99 ~Interface() {}
100 };
101
102 explicit ExcServer(Interface* interface);
103
104 // MachMessageServer::Interface:
105
106 virtual bool MachMessageServerFunction(
107 mach_msg_header_t* in_header,
108 mach_msg_header_t* out_header,
109 bool* destroy_complex_request) override;
110
111 virtual mach_msg_size_t MachMessageServerRequestSize() override;
112 virtual mach_msg_size_t MachMessageServerReplySize() override;
113
114 private:
115 Interface* interface_; // weak
116 };
117
118 //! \brief A server interface for the `mach_exc` Mach subsystem.
119 class MachExcServer : public MachMessageServer::Interface {
120 public:
121 //! \brief An interface that the different request messages that are a part of
122 //! the `mach_exc` Mach subsystem can be dispatched to.
123 class Interface {
124 public:
125 //! \brief Handles exceptions raised by `mach_exception_raise()`.
126 //!
127 //! This behaves equivalently to a `catch_mach_exception_raise()` function
128 //! used with `mach_exc_server()`.
129 //!
130 //! \param[out] destroy_request `true` if the request message is to be
131 //! destroyed even when this method returns success. See
132 //! MachMessageServer::Interface.
133 virtual kern_return_t CatchMachExceptionRaise(
134 exception_handler_t exception_port,
135 thread_t thread,
136 task_t task,
137 exception_type_t exception,
138 const mach_exception_data_type_t* code,
139 mach_msg_type_number_t code_count,
140 bool* destroy_request) = 0;
141
142 //! \brief Handles exceptions raised by `mach_exception_raise_state()`.
143 //!
144 //! This behaves equivalently to a `catch_mach_exception_raise_state()`
145 //! function used with `mach_exc_server()`.
146 //!
147 //! There is no \a destroy_request parameter because, unlike
148 //! CatchMachExceptionRaise() and CatchMachExceptionRaiseStateIdentity(),
149 //! the request message is not complex (it does not carry the \a thread or
150 //! \a task port rights) and thus there is nothing to destroy.
151 virtual kern_return_t CatchMachExceptionRaiseState(
152 exception_handler_t exception_port,
153 exception_type_t exception,
154 const mach_exception_data_type_t* code,
155 mach_msg_type_number_t code_count,
156 thread_state_flavor_t* flavor,
157 const natural_t* old_state,
158 mach_msg_type_number_t old_state_count,
159 thread_state_t new_state,
160 mach_msg_type_number_t* new_state_count) = 0;
161
162 //! \brief Handles exceptions raised by
163 //! `mach_exception_raise_state_identity()`.
164 //!
165 //! This behaves equivalently to a
166 //! `catch_mach_exception_raise_state_identity()` function used with
167 //! `mach_exc_server()`.
168 //!
169 //! \param[out] destroy_request `true` if the request message is to be
170 //! destroyed even when this method returns success. See
171 //! MachMessageServer::Interface.
172 virtual kern_return_t CatchMachExceptionRaiseStateIdentity(
173 exception_handler_t exception_port,
174 thread_t thread,
175 task_t task,
176 exception_type_t exception,
177 const mach_exception_data_type_t* code,
178 mach_msg_type_number_t code_count,
179 thread_state_flavor_t* flavor,
180 const natural_t* old_state,
181 mach_msg_type_number_t old_state_count,
182 thread_state_t new_state,
183 mach_msg_type_number_t* new_state_count,
184 bool* destroy_request) = 0;
185
186 protected:
187 ~Interface() {}
188 };
189
190 explicit MachExcServer(Interface* interface);
191
192 // MachMessageServer::Interface:
193
194 virtual bool MachMessageServerFunction(
195 mach_msg_header_t* in_header,
196 mach_msg_header_t* out_header,
197 bool* destroy_complex_request) override;
198
199 virtual mach_msg_size_t MachMessageServerRequestSize() override;
200 virtual mach_msg_size_t MachMessageServerReplySize() override;
201
202 private:
203 Interface* interface_; // weak
204 };
205
206 //! \brief A server interface for the `exc` Mach subsystem, simplified to have
207 //! only a single interface method needing implementation.
208 class SimplifiedExcServer : public ExcServer, public ExcServer::Interface {
209 public:
210 //! \brief An interface that the different request messages that are a part of
211 //! the `exc` Mach subsystem can be dispatched to.
212 class Interface {
213 public:
214 //! \brief Handles exceptions raised by `exception_raise()`,
215 //! `exception_raise_state()`, and `exception_raise_state_identity()`.
216 //!
217 //! For convenience in implementation, these different “behaviors” of
218 //! exception messages are all mapped to a single interface method. The
219 //! exception’s original “behavior” is specified in the \a behavior
220 //! parameter. Only parameters that were supplied in the request message
221 //! are populated, other parameters are set to reasonable default values.
222 //!
223 //! The meanings of most parameters are identical to that of
224 //! ExcServer::Interface::CatchExceptionRaiseStateIdentity().
225 //!
226 //! \param[in] behavior `EXCEPTION_DEFAULT`, `EXCEPTION_STATE`, or
227 //! `EXCEPTION_STATE_IDENTITY`, identifying which exception request
228 //! message was processed and thus which other parameters are valid.
229 virtual kern_return_t CatchException(
230 exception_behavior_t behavior,
231 exception_handler_t exception_port,
232 thread_t thread,
233 task_t task,
234 exception_type_t exception,
235 const exception_data_type_t* code,
236 mach_msg_type_number_t code_count,
237 thread_state_flavor_t* flavor,
238 const natural_t* old_state,
239 mach_msg_type_number_t old_state_count,
240 thread_state_t new_state,
241 mach_msg_type_number_t* new_state_count,
242 bool* destroy_complex_request) = 0;
243
244 protected:
245 ~Interface() {}
246 };
247
248 explicit SimplifiedExcServer(Interface* interface);
249
250 // ExcServer::Interface:
251
252 virtual kern_return_t CatchExceptionRaise(
253 exception_handler_t exception_port,
254 thread_t thread,
255 task_t task,
256 exception_type_t exception,
257 const exception_data_type_t* code,
258 mach_msg_type_number_t code_count,
259 bool* destroy_request) override;
260 virtual kern_return_t CatchExceptionRaiseState(
261 exception_handler_t exception_port,
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) override;
270 virtual kern_return_t CatchExceptionRaiseStateIdentity(
271 exception_handler_t exception_port,
272 thread_t thread,
273 task_t task,
274 exception_type_t exception,
275 const exception_data_type_t* code,
276 mach_msg_type_number_t code_count,
277 thread_state_flavor_t* flavor,
278 const natural_t* old_state,
279 mach_msg_type_number_t old_state_count,
280 thread_state_t new_state,
281 mach_msg_type_number_t* new_state_count,
282 bool* destroy_request) override;
283
284 private:
285 Interface* interface_; // weak
286 };
287
288 //! \brief A server interface for the `mach_exc` Mach subsystem, simplified to
289 //! have only a single interface method needing implementation.
290 class SimplifiedMachExcServer : public MachExcServer,
291 public MachExcServer::Interface {
292 public:
293 //! \brief An interface that the different request messages that are a part of
294 //! the `mach_exc` Mach subsystem can be dispatched to.
295 class Interface {
296 public:
297 //! \brief Handles exceptions raised by `mach_exception_raise()`,
298 //! `mach_exception_raise_state()`, and
299 //! `mach_exception_raise_state_identity()`.
300 //!
301 //! When used with UniversalMachExcServer, this also handles exceptions
302 //! raised by `exception_raise()`, `exception_raise_state()`, and
303 //! `exception_raise_state_identity()`.
304 //!
305 //! For convenience in implementation, these different “behaviors” of
306 //! exception messages are all mapped to a single interface method. The
307 //! exception’s original “behavior” is specified in the \a behavior
308 //! parameter. Only parameters that were supplied in the request message
309 //! are populated, other parameters are set to reasonable default values.
310 //!
311 //! The meanings of most parameters are identical to that of
312 //! MachExcServer::Interface::CatchMachExceptionRaiseStateIdentity().
313 //!
314 //! \param[in] behavior `MACH_EXCEPTION_CODES | EXCEPTION_DEFAULT`,
315 //! `MACH_EXCEPTION_CODES | EXCEPTION_STATE`, or
316 //! `MACH_EXCEPTION_CODES | EXCEPTION_STATE_IDENTITY`, identifying which
317 //! exception request message was processed and thus which other
318 //! parameters are valid. When used with UniversalMachExcServer, \a
319 //! behavior can also be `EXCEPTION_DEFAULT`, `EXCEPTION_STATE`, or
320 //! `EXCEPTION_STATE_IDENTITY`.
321 virtual kern_return_t CatchMachException(
322 exception_behavior_t behavior,
323 exception_handler_t exception_port,
324 thread_t thread,
325 task_t task,
326 exception_type_t exception,
327 const mach_exception_data_type_t* code,
328 mach_msg_type_number_t code_count,
329 thread_state_flavor_t* flavor,
330 const natural_t* old_state,
331 mach_msg_type_number_t old_state_count,
332 thread_state_t new_state,
333 mach_msg_type_number_t* new_state_count,
334 bool* destroy_complex_request) = 0;
335
336 protected:
337 ~Interface() {}
338 };
339
340 explicit SimplifiedMachExcServer(Interface* interface);
341
342 // MachExcServer::Interface:
343
344 virtual kern_return_t CatchMachExceptionRaise(
345 exception_handler_t exception_port,
346 thread_t thread,
347 task_t task,
348 exception_type_t exception,
349 const mach_exception_data_type_t* code,
350 mach_msg_type_number_t code_count,
351 bool* destroy_request) override;
352 virtual kern_return_t CatchMachExceptionRaiseState(
353 exception_handler_t exception_port,
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) override;
362 virtual kern_return_t CatchMachExceptionRaiseStateIdentity(
363 exception_handler_t exception_port,
364 thread_t thread,
365 task_t task,
366 exception_type_t exception,
367 const mach_exception_data_type_t* code,
368 mach_msg_type_number_t code_count,
369 thread_state_flavor_t* flavor,
370 const natural_t* old_state,
371 mach_msg_type_number_t old_state_count,
372 thread_state_t new_state,
373 mach_msg_type_number_t* new_state_count,
374 bool* destroy_request) override;
375
376 private:
377 Interface* interface_; // weak
378 };
379
380 } // namespace internal
381
382 //! \brief A server interface for the `exc` and `mach_exc` Mach subsystems,
383 //! unified to handle exceptions delivered to either subsystem, and
384 //! simplified to have only a single interface method needing
385 //! implementation.
386 //!
387 //! UniversalMachExcServer operates by translating messages received in the
388 //! `exc` subsystem to a variant that is compatible with the `mach_exc`
389 //! subsystem. This involves changing the format of \a code, the exception code
390 //! field, from `exception_data_type_t` to `mach_exception_data_type_t`.
391 //! This is achieved by implementing SimplifiedExcServer::Interface and having
392 //! it forward translated messages to SimplifiedMachExcServer::Interface, which
393 //! is left unimplemented here so that users of this class can provide their own
394 //! implementations.
395 class UniversalMachExcServer
396 : public MachMessageServer::Interface,
397 public internal::SimplifiedExcServer::Interface,
398 public internal::SimplifiedMachExcServer::Interface {
399 public:
400 UniversalMachExcServer();
401
402 // MachMessageServer::Interface:
403
404 virtual bool MachMessageServerFunction(
405 mach_msg_header_t* in_header,
406 mach_msg_header_t* out_header,
407 bool* destroy_complex_request) override;
408
409 virtual mach_msg_size_t MachMessageServerRequestSize() override;
410 virtual mach_msg_size_t MachMessageServerReplySize() override;
411
412 // internal::SimplifiedExcServer::Interface:
413
414 virtual kern_return_t CatchException(
415 exception_behavior_t behavior,
416 exception_handler_t exception_port,
417 thread_t thread,
418 task_t task,
419 exception_type_t exception,
420 const exception_data_type_t* code,
421 mach_msg_type_number_t code_count,
422 thread_state_flavor_t* flavor,
423 const natural_t* old_state,
424 mach_msg_type_number_t old_state_count,
425 thread_state_t new_state,
426 mach_msg_type_number_t* new_state_count,
427 bool* destroy_complex_request) override;
428
429 private:
430 internal::SimplifiedExcServer exc_server_;
431 internal::SimplifiedMachExcServer mach_exc_server_;
432 };
433
434 } // namespace crashpad
435
436 #endif // CRASHPAD_UTIL_MACH_EXC_SERVER_VARIANTS_H_
OLDNEW
« no previous file with comments | « util/mach/bootstrap_test.cc ('k') | util/mach/exc_server_variants.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698