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

Unified 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 side-by-side diff with in-line comments
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 »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: util/mach/exception_ports.cc
diff --git a/util/mach/exception_ports.cc b/util/mach/exception_ports.cc
new file mode 100644
index 0000000000000000000000000000000000000000..b96517c64bdbc513777eb12ebdfc9e962bef4fa7
--- /dev/null
+++ b/util/mach/exception_ports.cc
@@ -0,0 +1,131 @@
+// Copyright 2014 The Crashpad Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "util/mach/exception_ports.h"
+
+#include "base/logging.h"
+#include "base/mac/mach_logging.h"
+
+namespace crashpad {
+
+ExceptionPorts::ExceptionPorts(TargetType target_type, mach_port_t target_port)
+ : target_port_(target_port), dealloc_target_port_(false) {
+ switch (target_type) {
+ case kTargetTypeHost:
+ get_exception_ports_ = host_get_exception_ports;
+ set_exception_ports_ = host_set_exception_ports;
+ target_name_ = "host";
+ if (target_port_ == MACH_PORT_NULL) {
+ target_port_ = mach_host_self();
+ dealloc_target_port_ = true;
+ }
+ break;
+
+ case kTargetTypeTask:
+ get_exception_ports_ = task_get_exception_ports;
+ set_exception_ports_ = task_set_exception_ports;
+ target_name_ = "task";
+ if (target_port_ == MACH_PORT_NULL) {
+ target_port_ = mach_task_self();
+ // Don’t deallocate mach_task_self().
+ }
+ break;
+
+ case kTargetTypeThread:
+ get_exception_ports_ = thread_get_exception_ports;
+ set_exception_ports_ = thread_set_exception_ports;
+ target_name_ = "thread";
+ if (target_port_ == MACH_PORT_NULL) {
+ target_port_ = mach_thread_self();
+ dealloc_target_port_ = true;
+ }
+ break;
+
+ default:
+ NOTREACHED();
+ get_exception_ports_ = NULL;
+ set_exception_ports_ = NULL;
+ target_name_ = NULL;
+ target_port_ = MACH_PORT_NULL;
+ break;
+ }
+}
+
+ExceptionPorts::~ExceptionPorts() {
+ if (dealloc_target_port_) {
+ kern_return_t kr = mach_port_deallocate(mach_task_self(), target_port_);
+ MACH_LOG_IF(ERROR, kr != KERN_SUCCESS, kr) << "mach_port_deallocate";
+ }
+}
+
+bool ExceptionPorts::GetExceptionPorts(
+ exception_mask_t mask,
+ std::vector<ExceptionHandler>* handlers) const {
+ // <mach/mach_types.defs> says that these arrays have room for 32 elements,
+ // despite EXC_TYPES_COUNT only being as low as 11 (in the 10.6 SDK), and
+ // later operating system versions have defined more exception types. The
+ // generated task_get_exception_ports() in taskUser.c expects there to be room
+ // for 32.
+ const int kMaxPorts = 32;
+
+ // task_get_exception_ports() doesn’t actually use the initial value of
+ // handler_count, but 10.9.4
+ // xnu-2422.110.17/osfmk/man/task_get_exception_ports.html says it does. Humor
+ // the documentation.
+ mach_msg_type_number_t handler_count = kMaxPorts;
+
+ exception_mask_t masks[kMaxPorts];
+ exception_handler_t ports[kMaxPorts];
+ exception_behavior_t behaviors[kMaxPorts];
+ thread_state_flavor_t flavors[kMaxPorts];
+
+ kern_return_t kr = get_exception_ports_(
+ target_port_, mask, masks, &handler_count, ports, behaviors, flavors);
+ if (kr != KERN_SUCCESS) {
+ MACH_LOG(ERROR, kr) << TargetTypeName() << "_get_exception_ports";
+ return false;
+ }
+
+ handlers->clear();
+ for (mach_msg_type_number_t index = 0; index < handler_count; ++index) {
+ ExceptionHandler handler;
+ handler.mask = masks[index];
+ handler.port = ports[index];
+ handler.behavior = behaviors[index];
+ handler.flavor = flavors[index];
+ handlers->push_back(handler);
+ }
+
+ return true;
+}
+
+bool ExceptionPorts::SetExceptionPort(exception_mask_t mask,
+ exception_handler_t port,
+ exception_behavior_t behavior,
+ thread_state_flavor_t flavor) const {
+ kern_return_t kr =
+ set_exception_ports_(target_port_, mask, port, behavior, flavor);
+ if (kr != KERN_SUCCESS) {
+ MACH_LOG(ERROR, kr) << TargetTypeName() << "_set_exception_ports";
+ return false;
+ }
+
+ return true;
+}
+
+const char* ExceptionPorts::TargetTypeName() const {
+ return target_name_;
+}
+
+} // namespace crashpad
« 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