in Source/PLCrashReporter.m [260:323]
static kern_return_t mach_exception_callback (task_t task, thread_t thread, exception_type_t exception_type, mach_exception_data_t code, mach_msg_type_number_t code_count, void *context) {
plcrashreporter_handler_ctx_t *sigctx = context;
plcrash_log_signal_info_t signal_info;
plcrash_log_bsd_signal_info_t bsd_signal_info;
plcrash_log_mach_signal_info_t mach_signal_info;
plcrash_error_t err;
/* Let any other registered server attempt to handle the exception */
if (PLCrashMachExceptionForward(task, thread, exception_type, code, code_count, &sigctx->port_set) == KERN_SUCCESS)
return KERN_SUCCESS;
/* Set up the BSD signal info */
siginfo_t si;
if (!plcrash_async_mach_exception_get_siginfo(exception_type, code, code_count, CPU_TYPE_ANY, &si)) {
PLCF_DEBUG("Unexpected error mapping Mach exception to a POSIX signal");
return KERN_FAILURE;
}
bsd_signal_info.signo = si.si_signo;
bsd_signal_info.code = si.si_code;
bsd_signal_info.address = si.si_addr;
signal_info.bsd_info = &bsd_signal_info;
/* Set up the Mach signal info */
mach_signal_info.type = exception_type;
mach_signal_info.code = code;
mach_signal_info.code_count = code_count;
signal_info.mach_info = &mach_signal_info;
/* Write the report */
struct mach_exception_callback_live_cb_ctx live_ctx = {
.sigctx = sigctx,
.crashed_thread = thread,
.siginfo = &signal_info
};
if ((err = plcrash_async_thread_state_current(mach_exception_callback_live_cb, &live_ctx)) != PLCRASH_ESUCCESS) {
PLCF_DEBUG("Failed to write live report: %d", err);
return KERN_FAILURE;
}
/* Call any post-crash callback */
if (crashCallbacks.handleSignal != NULL) {
/*
* The legacy signal-based callback assumes the availability of a ucontext_t; we mock
* an empty value here for the purpose of maintaining backwards compatibility. This behavior
* is defined in the PLCrashReporterCallbacks API documentation.
*/
ucontext_t uctx;
_STRUCT_MCONTEXT mctx;
/* Populate the mctx */
plcrash_async_memset(&mctx, 0, sizeof(mctx));
/* Configure the ucontext */
plcrash_async_memset(&uctx, 0, sizeof(uctx));
uctx.uc_mcsize = sizeof(mctx);
uctx.uc_mcontext = &mctx;
crashCallbacks.handleSignal(&si, &uctx, crashCallbacks.context);
}
return KERN_FAILURE;
}