crashpad/util/mach/exception_ports.h
Mark Mentovai de0979b930 C++11: Use type aliases instead of typedefs.
This replaces all occurrences of “typedef Y X;” with “using X = Y;”.

R=rsesek@chromium.org

Review URL: https://codereview.chromium.org/700143004
2014-11-05 14:09:01 -05:00

188 lines
8.6 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 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.
#ifndef CRASHPAD_UTIL_MACH_EXCEPTION_PORTS_H_
#define CRASHPAD_UTIL_MACH_EXCEPTION_PORTS_H_
#include <mach/mach.h>
#include <vector>
#include "base/basictypes.h"
namespace crashpad {
//! \brief A better interface to `*_get_exception_ports()` and
//! `*_set_exception_ports()`.
//!
//! The same generic interface can be used to operate on host, task, and thread
//! exception ports. The “get” interface is superior to the systems native
//! interface because it keeps related data about a single exception handler
//! together in one struct, rather than separating it into four parallel arrays.
class ExceptionPorts {
public:
//! \brief Various entities which can have their own exception ports set.
enum TargetType {
//! \brief The host exception target.
//!
//! `host_get_exception_ports()` and `host_set_exception_ports()` will be
//! used. If no target port is explicitly provided, `mach_host_self()` will
//! be used as the target port. `mach_host_self()` is the only target port
//! for this type that is expected to function properly.
//!
//! \note Operations on this target type are not expected to succeed as
//! non-root, because `mach_host_self()` doesnt return the privileged
//! `host_priv` port to non-root users, and this is the target port
//! thats required for `host_get_exception_ports()` and
//! `host_set_exception_ports()`.
kTargetTypeHost = 0,
//! \brief A task exception target.
//!
//! `task_get_exception_ports()` and `task_set_exception_ports()` will be
//! used. If no target port is explicitly provided, `mach_task_self()` will
//! be used as the target port.
kTargetTypeTask,
//! \brief A thread exception target.
//!
//! `thread_get_exception_ports()` and `thread_set_exception_ports()` will
//! be used. If no target port is explicitly provided, `mach_thread_self()`
//! will be used as the target port.
kTargetTypeThread,
};
//! \brief Information about a registered exception handler.
struct ExceptionHandler {
//! \brief A mask specifying the exception types to direct to \a port,
//! containing `EXC_MASK_*` values.
exception_mask_t mask;
//! \brief A send right to a Mach port that will handle exceptions of the
//! types indicated in \a mask.
exception_handler_t port;
//! \brief The “behavior” that the exception handler at \a port implements:
//! `EXCEPTION_DEFAULT`, `EXCEPTION_STATE`, or
//! `EXCEPTION_STATE_IDENTITY`, possibly combined with
//! `MACH_EXCEPTION_CODES`.
exception_behavior_t behavior;
//! \brief The thread state flavor that the exception handler at \a port
//! will receive and possibly modify. This member has no effect for \a
//! \a behavior values that indicate a “default” behavior.
thread_state_flavor_t flavor;
};
//! \brief Constructs an interface object to get or set exception ports on a
//! host, task, or thread port.
//!
//! \param[in] target_type The type of target on which the exception ports are
//! to be get or set: #kTargetTypeHost, #kTargetTypeTask, or or
//! #kTargetTypeThread. The correct functions for
//! `*_get_exception_ports()` and `*_set_exception_ports()` will be used.
//! \param[in] target_port The target on which to call
//! `*_get_exception_ports()` or `*_set_exception_ports()`. The target
//! port must be a send right to a port of the type specified in \a
//! target_type. In this case, ownership of \a target_port is not given to
//! the new ExceptionPorts object. \a target_port may also be
//! `HOST_NULL`, `TASK_NULL`, or `THREAD_NULL`, in which case
//! `mach_host_self()`, `mach_task_self()`, or `mach_thread_self()` will
//! be used as the target port depending on the value of \a target_type.
//! In this case, ownership of the target port will be managed
//! appropriately for \a target_type.
ExceptionPorts(TargetType target_type, mach_port_t target_port);
~ExceptionPorts();
//! \brief Calls `*_get_exception_ports()` on the target.
//!
//! \param[in] mask The exception mask, containing the `EXC_MASK_*` values to
//! be looked up and returned in \a handlers.
//! \param[out] handlers The exception handlers registered for \a target_port
//! to handle exceptions indicated in \a mask. The caller must take
//! ownership of the \a port members of the returned ExceptionHandler
//! objects. If no execption port is registered for a bit in \a mask, \a
//! handlers will not contain an entry corresponding to that bit. This is
//! a departure from the `*_get_exception_ports()` functions, which may
//! return a handler whose port is set to `EXCEPTION_PORT_NULL` in this
//! case. On failure, this argument is untouched.
//!
//! \return `true` if `*_get_exception_ports()` returned `KERN_SUCCESS`, with
//! \a handlers set appropriately. `false` otherwise, with an appropriate
//! message logged.
bool GetExceptionPorts(exception_mask_t mask,
std::vector<ExceptionHandler>* handlers) const;
//! \brief Calls `*_set_exception_ports()` on the target.
//!
//! \param[in] mask A mask specifying the exception types to direct to \a
//! port, containing `EXC_MASK_*` values.
//! \param[in] port A send right to a Mach port that will handle exceptions
//! sustained by \a target_port of the types indicated in \a mask. The
//! send right is copied, not consumed, by this call.
//! \param[in] behavior The “behavior” that the exception handler at \a port
//! implements: `EXCEPTION_DEFAULT`, `EXCEPTION_STATE`, or
//! `EXCEPTION_STATE_IDENTITY`, possibly combined with
//! `MACH_EXCEPTION_CODES`.
//! \param[in] flavor The thread state flavor that the exception handler at \a
//! port expects to receive and possibly modify. This argument has no
//! effect for \a behavior values that indicate a “default” behavior.
//!
//! \return `true` if `*_set_exception_ports()` returned `KERN_SUCCESS`.
//! `false` otherwise, with an appropriate message logged.
bool SetExceptionPort(exception_mask_t mask,
exception_handler_t port,
exception_behavior_t behavior,
thread_state_flavor_t flavor) const;
//! \brief Returns a string identifying the target type.
//!
//! \return `"host"`, `"task"`, or `"thread"`, as appropriate.
const char* TargetTypeName() const;
private:
using GetExceptionPortsType = kern_return_t(*)(mach_port_t,
exception_mask_t,
exception_mask_array_t,
mach_msg_type_number_t*,
exception_handler_array_t,
exception_behavior_array_t,
exception_flavor_array_t);
using SetExceptionPortsType = kern_return_t(*)(mach_port_t,
exception_mask_t,
exception_handler_t,
exception_behavior_t,
thread_state_flavor_t);
GetExceptionPortsType get_exception_ports_;
SetExceptionPortsType set_exception_ports_;
const char* target_name_;
mach_port_t target_port_;
// If true, target_port_ will be deallocated in the destructor. This will
// always be false when the user provides a non-null target_port to the
// constructor. It will also be false when target_type is kTargetTypeTask,
// even with a TASK_NULL target_port, because it is incorrect to deallocate
// the result of mach_task_self().
bool dealloc_target_port_;
DISALLOW_COPY_AND_ASSIGN(ExceptionPorts);
};
} // namespace crashpad
#endif // CRASHPAD_UTIL_MACH_EXCEPTION_PORTS_H_