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

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
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..8d7fb2891441de8406cc17ed3625ff558f6b1848
--- /dev/null
+++ b/util/mach/exception_ports.cc
@@ -0,0 +1,126 @@
+// 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_);
+ if (kr != KERN_SUCCESS) {
+ MACH_LOG(ERROR, kr) << "mach_port_deallocate";
Robert Sesek 2014/09/16 17:38:09 MACH_LOG_IF ?
+ }
+ }
+}
+
+kern_return_t 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) {
Robert Sesek 2014/09/16 17:38:09 In many other cases, you return bool and then log
+ return kr;
+ }
+
+ 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 kr;
+}
+
+kern_return_t ExceptionPorts::SetExceptionPort(
+ exception_mask_t mask,
+ exception_handler_t port,
+ exception_behavior_t behavior,
+ thread_state_flavor_t flavor) const {
+ return set_exception_ports_(target_port_, mask, port, behavior, flavor);
+}
+
+const char* ExceptionPorts::TargetTypeName() const {
+ return target_name_;
+}
+
+} // namespace crashpad

Powered by Google App Engine
This is Rietveld 408576698