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 |