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

Side by Side Diff: util/mach/exception_ports.cc

Issue 549023005: Add ExceptionPorts and its test (Closed) Base URL: https://chromium.googlesource.com/crashpad/crashpad@master
Patch Set: Rebase 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/exception_ports.h ('k') | util/mach/exception_ports_test.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 #include "util/mach/exception_ports.h"
16
17 #include "base/logging.h"
18 #include "base/mac/mach_logging.h"
19
20 namespace crashpad {
21
22 ExceptionPorts::ExceptionPorts(TargetType target_type, mach_port_t target_port)
23 : target_port_(target_port), dealloc_target_port_(false) {
24 switch (target_type) {
25 case kTargetTypeHost:
26 get_exception_ports_ = host_get_exception_ports;
27 set_exception_ports_ = host_set_exception_ports;
28 target_name_ = "host";
29 if (target_port_ == MACH_PORT_NULL) {
30 target_port_ = mach_host_self();
31 dealloc_target_port_ = true;
32 }
33 break;
34
35 case kTargetTypeTask:
36 get_exception_ports_ = task_get_exception_ports;
37 set_exception_ports_ = task_set_exception_ports;
38 target_name_ = "task";
39 if (target_port_ == MACH_PORT_NULL) {
40 target_port_ = mach_task_self();
41 // Don’t deallocate mach_task_self().
42 }
43 break;
44
45 case kTargetTypeThread:
46 get_exception_ports_ = thread_get_exception_ports;
47 set_exception_ports_ = thread_set_exception_ports;
48 target_name_ = "thread";
49 if (target_port_ == MACH_PORT_NULL) {
50 target_port_ = mach_thread_self();
51 dealloc_target_port_ = true;
52 }
53 break;
54
55 default:
56 NOTREACHED();
57 get_exception_ports_ = NULL;
58 set_exception_ports_ = NULL;
59 target_name_ = NULL;
60 target_port_ = MACH_PORT_NULL;
61 break;
62 }
63 }
64
65 ExceptionPorts::~ExceptionPorts() {
66 if (dealloc_target_port_) {
67 kern_return_t kr = mach_port_deallocate(mach_task_self(), target_port_);
68 MACH_LOG_IF(ERROR, kr != KERN_SUCCESS, kr) << "mach_port_deallocate";
69 }
70 }
71
72 bool ExceptionPorts::GetExceptionPorts(
73 exception_mask_t mask,
74 std::vector<ExceptionHandler>* handlers) const {
75 // <mach/mach_types.defs> says that these arrays have room for 32 elements,
76 // despite EXC_TYPES_COUNT only being as low as 11 (in the 10.6 SDK), and
77 // later operating system versions have defined more exception types. The
78 // generated task_get_exception_ports() in taskUser.c expects there to be room
79 // for 32.
80 const int kMaxPorts = 32;
81
82 // task_get_exception_ports() doesn’t actually use the initial value of
83 // handler_count, but 10.9.4
84 // xnu-2422.110.17/osfmk/man/task_get_exception_ports.html says it does. Humor
85 // the documentation.
86 mach_msg_type_number_t handler_count = kMaxPorts;
87
88 exception_mask_t masks[kMaxPorts];
89 exception_handler_t ports[kMaxPorts];
90 exception_behavior_t behaviors[kMaxPorts];
91 thread_state_flavor_t flavors[kMaxPorts];
92
93 kern_return_t kr = get_exception_ports_(
94 target_port_, mask, masks, &handler_count, ports, behaviors, flavors);
95 if (kr != KERN_SUCCESS) {
96 MACH_LOG(ERROR, kr) << TargetTypeName() << "_get_exception_ports";
97 return false;
98 }
99
100 handlers->clear();
101 for (mach_msg_type_number_t index = 0; index < handler_count; ++index) {
102 ExceptionHandler handler;
103 handler.mask = masks[index];
104 handler.port = ports[index];
105 handler.behavior = behaviors[index];
106 handler.flavor = flavors[index];
107 handlers->push_back(handler);
108 }
109
110 return true;
111 }
112
113 bool ExceptionPorts::SetExceptionPort(exception_mask_t mask,
114 exception_handler_t port,
115 exception_behavior_t behavior,
116 thread_state_flavor_t flavor) const {
117 kern_return_t kr =
118 set_exception_ports_(target_port_, mask, port, behavior, flavor);
119 if (kr != KERN_SUCCESS) {
120 MACH_LOG(ERROR, kr) << TargetTypeName() << "_set_exception_ports";
121 return false;
122 }
123
124 return true;
125 }
126
127 const char* ExceptionPorts::TargetTypeName() const {
128 return target_name_;
129 }
130
131 } // namespace crashpad
OLDNEW
« no previous file with comments | « util/mach/exception_ports.h ('k') | util/mach/exception_ports_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698