static void next_exception_forwarded_reply (struct next_inferior_status *inferior, struct next_exception_data *erequest) { kern_return_t kret; struct next_exception_reply ereply; mach_port_t orig_reply_port = erequest->header.msg_remote_port; erequest->header.msg_remote_port = inferior->saved_exceptions.port; erequest->header.msg_local_port = inferior->exception_reply_port; inferior_debug ("sending exception to old exception port\n"); kret = msg_send (&erequest->header, MSG_OPTION_NONE, 0); MACH_CHECK_ERROR (kret); ereply.header.msg_size = sizeof (struct next_exception_reply); ereply.header.msg_local_port = inferior->exception_reply_port; inferior_debug ("receiving exception reply from old exception port\n"); kret = msg_receive (&ereply.header, RCV_LARGE, 0); MACH_CHECK_ERROR (kret); ereply.header.msg_local_port = PORT_NULL; ereply.header.msg_remote_port = orig_reply_port; inferior_debug ("sending exception reply\n"); kret = msg_send (&ereply.header, MSG_OPTION_NONE, 0); MACH_CHECK_ERROR (kret); }
kern_return_t next_inferior_resume_mach (next_inferior_status *s, int count) { kern_return_t kret; CHECK (s != NULL); CHECK (next_task_valid (s->task)); for (;;) { if (s->suspend_count == 0) { break; } if (count == 0) { break; } inferior_debug (2, "resuming task\n"); kret = task_resume (s->task); if (kret != KERN_SUCCESS) { return kret; } s->suspend_count--; count--; inferior_debug (2, "resumed task (suspend count now %d)\n", s->suspend_count); } return KERN_SUCCESS; }
static void next_exception_internal_reply (struct next_inferior_status *inferior, struct next_exception_data *erequest) { kern_return_t ret; struct next_exception_reply ereply; CHECK_FATAL (erequest->task == inferior->task); ereply.header.msg_unused = 0; ereply.header.msg_simple = 1; ereply.header.msg_size = sizeof (struct next_exception_reply); ereply.header.msg_type = erequest->header.msg_type; ereply.header.msg_local_port = PORT_NULL; ereply.header.msg_remote_port = erequest->header.msg_remote_port; ereply.header.msg_id = erequest->header.msg_id + 100; ereply.retcode_type.msg_type_name = MSG_TYPE_INTEGER_32; ereply.retcode_type.msg_type_size = sizeof (int) * 8; ereply.retcode_type.msg_type_number = 1; ereply.retcode_type.msg_type_inline = 1; ereply.retcode_type.msg_type_longform = 0; ereply.retcode_type.msg_type_deallocate = 0; ereply.retcode_type.msg_type_unused = 0; ereply.retcode = KERN_SUCCESS; inferior_debug ("sending exception reply\n"); ret = msg_send (&ereply.header, MSG_OPTION_NONE, 0); MACH_WARN_ERROR (ret); }
kern_return_t next_inferior_suspend_mach (next_inferior_status *s) { kern_return_t kret; CHECK (s != NULL); CHECK (next_task_valid (s->task)); if (s->suspend_count == 0) { inferior_debug (2, "suspending task\n"); kret = task_suspend (s->task); if (kret != KERN_SUCCESS) { return kret; } s->suspend_count++; inferior_debug (2, "suspended task (suspend count now %d)\n", s->suspend_count); } return KERN_SUCCESS; }
void next_handle_exception (struct next_inferior_status *inferior, msg_header_t *message, struct target_waitstatus *status) { next_exception_data* msg = (next_exception_data*) message; CHECK_FATAL (inferior != NULL); next_debug_exception (msg); if (msg->task != inferior->task) { inferior_debug ("ignoring exception forwarded from subprocess\n"); next_exception_forwarded_reply (inferior, msg); return; } inferior->last_thread = msg->thread; if (inferior_handle_exceptions_flag) { next_inferior_suspend_mach (inferior); next_exception_internal_reply (inferior, msg); status->kind = TARGET_WAITKIND_STOPPED; switch (msg->exception) { case EXC_BAD_ACCESS: status->value.sig = TARGET_EXC_BAD_ACCESS; break; case EXC_BAD_INSTRUCTION: status->value.sig = TARGET_EXC_BAD_INSTRUCTION; break; case EXC_ARITHMETIC: status->value.sig = TARGET_EXC_ARITHMETIC; break; case EXC_EMULATION: status->value.sig = TARGET_EXC_EMULATION; break; case EXC_SOFTWARE: status->value.sig = TARGET_EXC_SOFTWARE; break; case EXC_BREAKPOINT: status->value.sig = TARGET_EXC_BREAKPOINT; status->value.sig = TARGET_SIGNAL_TRAP; break; default: status->value.sig = TARGET_SIGNAL_UNKNOWN; break; } } else { next_exception_forwarded_reply (inferior, msg); } }
int call_ptrace(int request, int pid, PTRACE_ARG3_TYPE arg3, int arg4) { int ret; errno = 0; ret = ptrace(request, pid, (caddr_t)arg3, arg4); inferior_debug(2, "ptrace (%s, %d, %d, %d): %d (%s)\n", ptrace_request_unparse(request), pid, arg3, arg4, ret, ((ret != 0) ? xstrerror(errno) : "no error")); return ret; }