| Index: client/crashpad_client_mac.cc
|
| diff --git a/client/crashpad_client_mac.cc b/client/crashpad_client_mac.cc
|
| index 02067c9b73085dd4f4043b5737701b5b0e8c5528..e7ad064269f94acbd9fccf1bb1fd92005e12e32c 100644
|
| --- a/client/crashpad_client_mac.cc
|
| +++ b/client/crashpad_client_mac.cc
|
| @@ -26,6 +26,8 @@
|
| #include "util/mach/mach_extensions.h"
|
| #include "util/posix/close_multiple.h"
|
|
|
| +namespace crashpad {
|
| +
|
| namespace {
|
|
|
| std::string FormatArgumentString(const std::string& name,
|
| @@ -37,9 +39,45 @@ std::string FormatArgumentInt(const std::string& name, int value) {
|
| return base::StringPrintf("--%s=%d", name.c_str(), value);
|
| }
|
|
|
| -} // namespace
|
| +// Set the exception handler for EXC_CRASH, EXC_RESOURCE, and EXC_GUARD.
|
| +//
|
| +// EXC_CRASH is how most crashes are received. Most other exception types such
|
| +// as EXC_BAD_ACCESS are delivered to a host-level exception handler in the
|
| +// kernel where they are converted to POSIX signals. See 10.9.5
|
| +// xnu-2422.115.4/bsd/uxkern/ux_exception.c catch_mach_exception_raise(). If a
|
| +// core-generating signal (triggered through this hardware mechanism or a
|
| +// software mechanism such as abort() sending SIGABRT) is unhandled and the
|
| +// process exits, or if the process is killed with SIGKILL for code-signing
|
| +// reasons, an EXC_CRASH exception will be sent. See 10.9.5
|
| +// xnu-2422.115.4/bsd/kern/kern_exit.c proc_prepareexit().
|
| +//
|
| +// EXC_RESOURCE and EXC_GUARD do not become signals or EXC_CRASH exceptions. The
|
| +// host-level exception handler in the kernel does not receive these exception
|
| +// types, and even if it did, it would not map them to signals. Instead, the
|
| +// first Mach service loaded by the root (process ID 1) launchd with a boolean
|
| +// “ExceptionServer” property in its job dictionary (regardless of its value) or
|
| +// with any subdictionary property will become the host-level exception handler
|
| +// for EXC_CRASH, EXC_RESOURCE, and EXC_GUARD. See 10.9.5
|
| +// launchd-842.92.1/src/core.c job_setup_exception_port(). Normally, this job is
|
| +// com.apple.ReportCrash.Root, the systemwide Apple Crash Reporter. Since it is
|
| +// impossible to receive EXC_RESOURCE and EXC_GUARD exceptions through the
|
| +// EXC_CRASH mechanism, an exception handler must be registered for them by name
|
| +// if it is to receive these exception types. The default task-level handler for
|
| +// these exception types is set by launchd in a similar manner.
|
| +//
|
| +// EXC_MASK_RESOURCE and EXC_MASK_GUARD are not available on all systems, and
|
| +// the kernel will reject attempts to use them if it does not understand them,
|
| +// so AND them with ExcMaskValid(). EXC_MASK_CRASH is always supported.
|
| +bool SetCrashExceptionPorts(exception_handler_t exception_handler) {
|
| + ExceptionPorts exception_ports(ExceptionPorts::kTargetTypeTask, TASK_NULL);
|
| + return exception_ports.SetExceptionPort(
|
| + (EXC_MASK_CRASH | EXC_MASK_RESOURCE | EXC_MASK_GUARD) & ExcMaskValid(),
|
| + exception_handler,
|
| + EXCEPTION_STATE_IDENTITY | MACH_EXCEPTION_CODES,
|
| + MACHINE_THREAD_STATE);
|
| +}
|
|
|
| -namespace crashpad {
|
| +} // namespace
|
|
|
| CrashpadClient::CrashpadClient()
|
| : exception_port_() {
|
| @@ -179,46 +217,17 @@ bool CrashpadClient::StartHandler(
|
| bool CrashpadClient::UseHandler() {
|
| DCHECK_NE(exception_port_, kMachPortNull);
|
|
|
| - // Set the exception handler for EXC_CRASH, EXC_RESOURCE, and EXC_GUARD.
|
| - //
|
| - // EXC_CRASH is how most crashes are received. Most other exception types such
|
| - // as EXC_BAD_ACCESS are delivered to a host-level exception handler in the
|
| - // kernel where they are converted to POSIX signals. See 10.9.5
|
| - // xnu-2422.115.4/bsd/uxkern/ux_exception.c catch_mach_exception_raise(). If a
|
| - // core-generating signal (triggered through this hardware mechanism or a
|
| - // software mechanism such as abort() sending SIGABRT) is unhandled and the
|
| - // process exits, or if the process is killed with SIGKILL for code-signing
|
| - // reasons, an EXC_CRASH exception will be sent. See 10.9.5
|
| - // xnu-2422.115.4/bsd/kern/kern_exit.c proc_prepareexit().
|
| - //
|
| - // EXC_RESOURCE and EXC_GUARD do not become signals or EXC_CRASH exceptions.
|
| - // The host-level exception handler in the kernel does not receive these
|
| - // exception types, and even if it did, it would not map them to signals.
|
| - // Instead, the first Mach service loaded by the root (process ID 1) launchd
|
| - // with a boolean “ExceptionServer” property in its job dictionary (regardless
|
| - // of its value) or with any subdictionary property will become the host-level
|
| - // exception handler for EXC_CRASH, EXC_RESOURCE, and EXC_GUARD. See 10.9.5
|
| - // launchd-842.92.1/src/core.c job_setup_exception_port(). Normally, this job
|
| - // is com.apple.ReportCrash.Root, the systemwide Apple Crash Reporter. Since
|
| - // it is impossible to receive EXC_RESOURCE and EXC_GUARD exceptions through
|
| - // the EXC_CRASH mechanism, an exception handler must be registered for them
|
| - // by name if it is to receive these exception types. The default task-level
|
| - // handler for these exception types is set by launchd in a similar manner.
|
| - //
|
| - // EXC_MASK_RESOURCE and EXC_MASK_GUARD are not available on all systems, and
|
| - // the kernel will reject attempts to use them if it does not understand them,
|
| - // so AND them with ExcMaskValid(). EXC_MASK_CRASH is always supported.
|
| - ExceptionPorts exception_ports(ExceptionPorts::kTargetTypeTask, TASK_NULL);
|
| - if (!exception_ports.SetExceptionPort(
|
| - (EXC_MASK_CRASH | EXC_MASK_RESOURCE | EXC_MASK_GUARD) &
|
| - ExcMaskValid(),
|
| - exception_port_,
|
| - EXCEPTION_STATE_IDENTITY | MACH_EXCEPTION_CODES,
|
| - MACHINE_THREAD_STATE)) {
|
| - return false;
|
| - }
|
| + return SetCrashExceptionPorts(exception_port_);
|
| +}
|
| +
|
| +// static
|
| +bool CrashpadClient::UseSystemDefaultHandler() {
|
| + base::mac::ScopedMachSendRight
|
| + system_crash_reporter_handler(SystemCrashReporterHandler());
|
|
|
| - return true;
|
| + // Proceed even if SystemCrashReporterHandler() failed, setting MACH_PORT_NULL
|
| + // to clear the current exception ports.
|
| + return SetCrashExceptionPorts(system_crash_reporter_handler);
|
| }
|
|
|
| } // namespace crashpad
|
|
|