mirror of
https://github.com/chromium/crashpad.git
synced 2024-12-31 01:43:03 +08:00
032f1aecc2
Add direct includes for things provided transitively by logging.h (or by other headers including logging.h). This is in preparation for cleaning up unnecessary includes of logging.h in header files (so if something depends on logging.h, it needs include it explicitly), and for when Chromium's logging.h no longer includes check.h, check_op.h, and notreached.h. DEPS is also updated to roll mini_chromium to ae14a14ab4 which includes these new header files. Bug: chromium:1031540 Change-Id: I36f646d0a93854989dc602d0dc7139dd7a7b8621 Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/2250251 Commit-Queue: Hans Wennborg <hans@chromium.org> Reviewed-by: Mark Mentovai <mark@chromium.org>
214 lines
7.2 KiB
C++
214 lines
7.2 KiB
C++
// 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"
|
||
#include "base/notreached.h"
|
||
|
||
namespace crashpad {
|
||
|
||
ExceptionPorts::ExceptionHandlerVector::ExceptionHandlerVector()
|
||
: vector_() {
|
||
}
|
||
|
||
ExceptionPorts::ExceptionHandlerVector::~ExceptionHandlerVector() {
|
||
Deallocate();
|
||
}
|
||
|
||
void ExceptionPorts::ExceptionHandlerVector::clear() {
|
||
Deallocate();
|
||
vector_.clear();
|
||
}
|
||
|
||
void ExceptionPorts::ExceptionHandlerVector::Deallocate() {
|
||
for (ExceptionHandler& exception_handler : vector_) {
|
||
if (exception_handler.port != MACH_PORT_NULL) {
|
||
kern_return_t kr =
|
||
mach_port_deallocate(mach_task_self(), exception_handler.port);
|
||
MACH_LOG_IF(ERROR, kr != KERN_SUCCESS, kr) << "mach_port_deallocate";
|
||
}
|
||
}
|
||
}
|
||
|
||
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;
|
||
swap_exception_ports_ = host_swap_exception_ports;
|
||
target_name_ = "host";
|
||
if (target_port_ == HOST_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;
|
||
swap_exception_ports_ = task_swap_exception_ports;
|
||
target_name_ = "task";
|
||
if (target_port_ == TASK_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;
|
||
swap_exception_ports_ = thread_swap_exception_ports;
|
||
target_name_ = "thread";
|
||
if (target_port_ == THREAD_NULL) {
|
||
target_port_ = mach_thread_self();
|
||
dealloc_target_port_ = true;
|
||
}
|
||
break;
|
||
|
||
default:
|
||
NOTREACHED();
|
||
get_exception_ports_ = nullptr;
|
||
set_exception_ports_ = nullptr;
|
||
target_name_ = nullptr;
|
||
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,
|
||
ExceptionHandlerVector* 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.
|
||
constexpr 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) {
|
||
if (ports[index] != MACH_PORT_NULL) {
|
||
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;
|
||
}
|
||
|
||
bool ExceptionPorts::SwapExceptionPorts(
|
||
exception_mask_t mask,
|
||
exception_handler_t new_port,
|
||
exception_behavior_t new_behavior,
|
||
thread_state_flavor_t new_flavor,
|
||
ExceptionHandlerVector* old_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_swap_exception_ports() in taskUser.c expects there to be
|
||
// room for 32.
|
||
constexpr int kMaxPorts = 32;
|
||
|
||
// task_swap_exception_ports() doesn’t actually use the initial value of
|
||
// handler_count, but 10.15.1
|
||
// xnu-6153.41.3/osfmk/man/task_get_exception_ports.html says it does. Humor
|
||
// the documentation.
|
||
mach_msg_type_number_t old_handler_count = kMaxPorts;
|
||
|
||
exception_mask_t old_masks[kMaxPorts];
|
||
exception_handler_t old_ports[kMaxPorts];
|
||
exception_behavior_t old_behaviors[kMaxPorts];
|
||
thread_state_flavor_t old_flavors[kMaxPorts];
|
||
|
||
kern_return_t kr = swap_exception_ports_(target_port_,
|
||
mask,
|
||
new_port,
|
||
new_behavior,
|
||
new_flavor,
|
||
old_masks,
|
||
&old_handler_count,
|
||
old_ports,
|
||
old_behaviors,
|
||
old_flavors);
|
||
if (kr != KERN_SUCCESS) {
|
||
MACH_LOG(ERROR, kr) << TargetTypeName() << "_swap_exception_ports";
|
||
return false;
|
||
}
|
||
|
||
old_handlers->clear();
|
||
for (mach_msg_type_number_t index = 0; index < old_handler_count; ++index) {
|
||
if (old_ports[index] != MACH_PORT_NULL) {
|
||
ExceptionHandler old_handler;
|
||
old_handler.mask = old_masks[index];
|
||
old_handler.port = old_ports[index];
|
||
old_handler.behavior = old_behaviors[index];
|
||
old_handler.flavor = old_flavors[index];
|
||
old_handlers->push_back(old_handler);
|
||
}
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
const char* ExceptionPorts::TargetTypeName() const {
|
||
return target_name_;
|
||
}
|
||
|
||
} // namespace crashpad
|