supply instance to 2nd at_wini instance.
[minix3.git] / servers / pm / trace.c
blob8f4c3731461302006cf229bb49d56e3842a36962
1 /* This file handles the process manager's part of debugging, using the
2 * ptrace system call. Most of the commands are passed on to the system
3 * task for completion.
5 * The debugging commands available are:
6 * T_STOP stop the process
7 * T_OK enable tracing by parent for this process
8 * T_GETINS return value from instruction space
9 * T_GETDATA return value from data space
10 * T_GETUSER return value from user process table
11 * T_SETINS set value in instruction space
12 * T_SETDATA set value in data space
13 * T_SETUSER set value in user process table
14 * T_RESUME resume execution
15 * T_EXIT exit
16 * T_STEP set trace bit
18 * The T_OK and T_EXIT commands are handled here, and the T_RESUME and
19 * T_STEP commands are partially handled here and completed by the system
20 * task. The rest are handled entirely by the system task.
23 #include "pm.h"
24 #include <minix/com.h>
25 #include <sys/ptrace.h>
26 #include <signal.h>
27 #include "mproc.h"
28 #include "param.h"
30 #define NIL_MPROC ((struct mproc *) 0)
32 FORWARD _PROTOTYPE( struct mproc *find_proc, (pid_t lpid) );
34 /*===========================================================================*
35 * do_trace *
36 *===========================================================================*/
37 PUBLIC int do_trace()
39 register struct mproc *child;
40 int r;
42 /* the T_OK call is made by the child fork of the debugger before it execs
43 * the process to be traced
45 if (m_in.request == T_OK) { /* enable tracing by parent for this proc */
46 mp->mp_flags |= TRACED;
47 mp->mp_reply.reply_trace = 0;
48 return(OK);
50 if (m_in.request == T_READB_INS)
52 /* Special hack for reading text segments */
53 if (mp->mp_effuid != SUPER_USER)
54 return(EPERM);
55 if ((child=find_proc(m_in.pid))==NIL_MPROC)
56 return(ESRCH);
58 r= sys_trace(m_in.request,child->mp_endpoint,m_in.taddr,&m_in.data);
59 if (r != OK) return(r);
61 mp->mp_reply.reply_trace = m_in.data;
62 return(OK);
64 if (m_in.request == T_WRITEB_INS)
66 /* Special hack for patching text segments */
67 if (mp->mp_effuid != SUPER_USER)
68 return(EPERM);
69 if ((child=find_proc(m_in.pid))==NIL_MPROC)
70 return(ESRCH);
72 r= sys_trace(m_in.request,child->mp_endpoint,m_in.taddr,&m_in.data);
73 if (r != OK) return(r);
75 mp->mp_reply.reply_trace = m_in.data;
76 return(OK);
79 if ((child=find_proc(m_in.pid))==NIL_MPROC || !(child->mp_flags & STOPPED)) {
80 return(ESRCH);
82 /* all the other calls are made by the parent fork of the debugger to
83 * control execution of the child
85 switch (m_in.request) {
86 case T_EXIT: /* exit */
87 pm_exit(child, (int) m_in.data, TRUE /*for_trace*/);
88 /* Do not reply to the caller until FS has processed the exit
89 * request.
91 return SUSPEND;
92 case T_RESUME:
93 case T_STEP: /* resume execution */
94 if (m_in.data < 0 || m_in.data > _NSIG) return(EIO);
95 if (m_in.data > 0) { /* issue signal */
96 child->mp_flags &= ~TRACED; /* so signal is not diverted */
97 sig_proc(child, (int) m_in.data);
98 child->mp_flags |= TRACED;
100 child->mp_flags &= ~STOPPED;
101 break;
103 r= sys_trace(m_in.request,child->mp_endpoint,m_in.taddr,&m_in.data);
104 if (r != OK) return(r);
106 mp->mp_reply.reply_trace = m_in.data;
107 return(OK);
110 /*===========================================================================*
111 * find_proc *
112 *===========================================================================*/
113 PRIVATE struct mproc *find_proc(lpid)
114 pid_t lpid;
116 register struct mproc *rmp;
118 for (rmp = &mproc[0]; rmp < &mproc[NR_PROCS]; rmp++)
119 if (rmp->mp_flags & IN_USE && rmp->mp_pid == lpid) return(rmp);
120 return(NIL_MPROC);
123 /*===========================================================================*
124 * stop_proc *
125 *===========================================================================*/
126 PUBLIC void stop_proc(rmp, signo)
127 register struct mproc *rmp;
128 int signo;
130 /* A traced process got a signal so stop it. */
132 register struct mproc *rpmp = mproc + rmp->mp_parent;
133 int r;
135 r= sys_trace(-1, rmp->mp_endpoint, 0L, (long *) 0);
136 if (r != OK) panic("pm", "sys_trace failed", r);
138 rmp->mp_flags |= STOPPED;
139 if (rpmp->mp_flags & WAITING) {
140 rpmp->mp_flags &= ~WAITING; /* parent is no longer waiting */
141 rpmp->mp_reply.reply_res2 = 0177 | (signo << 8);
142 setreply(rmp->mp_parent, rmp->mp_pid);
143 } else {
144 rmp->mp_sigstatus = signo;
146 return;