/*===========================================================================* * do_trace * *===========================================================================*/ PUBLIC int do_trace() { register struct mproc *child; /* the T_OK call is made by the child fork of the debugger before it execs * the process to be traced */ if (m_in.request == T_OK) { /* enable tracing by parent for this proc */ mp->mp_flags |= TRACED; mp->mp_reply.reply_trace = 0; return(OK); } if ((child=find_proc(m_in.pid))==NIL_MPROC || !(child->mp_flags & STOPPED)) { return(ESRCH); } /* all the other calls are made by the parent fork of the debugger to * control execution of the child */ switch (m_in.request) { case T_EXIT: /* exit */ pm_exit(child, (int) m_in.data); mp->mp_reply.reply_trace = 0; return(OK); case T_RESUME: case T_STEP: /* resume execution */ if (m_in.data < 0 || m_in.data > _NSIG) return(EIO); if (m_in.data > 0) { /* issue signal */ child->mp_flags &= ~TRACED; /* so signal is not diverted */ sig_proc(child, (int) m_in.data); child->mp_flags |= TRACED; } child->mp_flags &= ~STOPPED; break; } if (sys_trace(m_in.request,(int)(child-mproc),m_in.taddr,&m_in.data) != OK) return(-errno); mp->mp_reply.reply_trace = m_in.data; return(OK); }
/*===========================================================================* * service_pm_postponed * *===========================================================================*/ static void service_pm_postponed(void) { int r; vir_bytes pc, newsp; switch(job_call_nr) { case PM_EXEC: { endpoint_t proc_e; vir_bytes exec_path, stack_frame; size_t exec_path_len, stack_frame_len; proc_e = job_m_in.PM_PROC; exec_path = (vir_bytes) job_m_in.PM_PATH; exec_path_len = (size_t) job_m_in.PM_PATH_LEN; stack_frame = (vir_bytes) job_m_in.PM_FRAME; stack_frame_len = (size_t) job_m_in.PM_FRAME_LEN; r = pm_exec(proc_e, exec_path, exec_path_len, stack_frame, stack_frame_len, &pc, &newsp, job_m_in.PM_EXECFLAGS); /* Reply status to PM */ m_out.m_type = PM_EXEC_REPLY; m_out.PM_PROC = proc_e; m_out.PM_PC = (void*) pc; m_out.PM_STATUS = r; m_out.PM_NEWSP = (void *) newsp; } break; case PM_EXIT: { endpoint_t proc_e; proc_e = job_m_in.PM_PROC; pm_exit(proc_e); /* Reply dummy status to PM for synchronization */ m_out.m_type = PM_EXIT_REPLY; m_out.PM_PROC = proc_e; } break; case PM_DUMPCORE: { endpoint_t proc_e, traced_proc_e; int term_signal; vir_bytes core_path; proc_e = job_m_in.PM_PROC; traced_proc_e = job_m_in.PM_TRACED_PROC; term_signal = job_m_in.PM_TERM_SIG; core_path = (vir_bytes) job_m_in.PM_PATH; r = pm_dumpcore(proc_e, term_signal, core_path); /* Reply status to PM */ m_out.m_type = PM_CORE_REPLY; m_out.PM_PROC = proc_e; m_out.PM_TRACED_PROC = traced_proc_e; m_out.PM_STATUS = r; } break; default: panic("Unhandled postponed PM call %d", job_m_in.m_type); } r = send(PM_PROC_NR, &m_out); if (r != OK) panic("service_pm_postponed: send failed: %d", r); }
/*===========================================================================* * service_pm_postponed * *===========================================================================*/ void service_pm_postponed(void) { int r, term_signal; vir_bytes core_path; vir_bytes exec_path, stack_frame, pc, newsp, ps_str; size_t exec_path_len, stack_frame_len; endpoint_t proc_e; message m_out; memset(&m_out, 0, sizeof(m_out)); switch(job_call_nr) { case VFS_PM_EXEC: proc_e = job_m_in.VFS_PM_ENDPT; exec_path = (vir_bytes) job_m_in.VFS_PM_PATH; exec_path_len = (size_t) job_m_in.VFS_PM_PATH_LEN; stack_frame = (vir_bytes) job_m_in.VFS_PM_FRAME; stack_frame_len = (size_t) job_m_in.VFS_PM_FRAME_LEN; ps_str = (vir_bytes) job_m_in.VFS_PM_PS_STR; assert(proc_e == fp->fp_endpoint); r = pm_exec(exec_path, exec_path_len, stack_frame, stack_frame_len, &pc, &newsp, &ps_str); /* Reply status to PM */ m_out.m_type = VFS_PM_EXEC_REPLY; m_out.VFS_PM_ENDPT = proc_e; m_out.VFS_PM_PC = (void *) pc; m_out.VFS_PM_STATUS = r; m_out.VFS_PM_NEWSP = (void *) newsp; m_out.VFS_PM_NEWPS_STR = ps_str; break; case VFS_PM_EXIT: proc_e = job_m_in.VFS_PM_ENDPT; assert(proc_e == fp->fp_endpoint); pm_exit(); /* Reply dummy status to PM for synchronization */ m_out.m_type = VFS_PM_EXIT_REPLY; m_out.VFS_PM_ENDPT = proc_e; break; case VFS_PM_DUMPCORE: proc_e = job_m_in.VFS_PM_ENDPT; term_signal = job_m_in.VFS_PM_TERM_SIG; core_path = (vir_bytes) job_m_in.VFS_PM_PATH; /* A zero signal used to indicate that a coredump should be generated * without terminating the target process, but this was broken in so * many ways that we no longer support this. Userland should implement * this functionality itself, for example through ptrace(2). */ if (term_signal == 0) panic("no termination signal given for coredump!"); assert(proc_e == fp->fp_endpoint); r = pm_dumpcore(term_signal, core_path); /* Reply status to PM */ m_out.m_type = VFS_PM_CORE_REPLY; m_out.VFS_PM_ENDPT = proc_e; m_out.VFS_PM_STATUS = r; break; case VFS_PM_UNPAUSE: proc_e = job_m_in.VFS_PM_ENDPT; assert(proc_e == fp->fp_endpoint); unpause(); m_out.m_type = VFS_PM_UNPAUSE_REPLY; m_out.VFS_PM_ENDPT = proc_e; break; default: panic("Unhandled postponed PM call %d", job_m_in.m_type); } r = ipc_send(PM_PROC_NR, &m_out); if (r != OK) panic("service_pm_postponed: ipc_send failed: %d", r); }