source: trunk/minix/servers/pm/trace.c@ 15

Last change on this file since 15 was 9, checked in by Mattia Monga, 14 years ago

Minix 3.1.2a

File size: 3.5 KB
RevLine 
[9]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.
4 *
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
17 *
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.
21 */
22
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"
29
30#define NIL_MPROC ((struct mproc *) 0)
31
32FORWARD _PROTOTYPE( struct mproc *find_proc, (pid_t lpid) );
33
34/*===========================================================================*
35 * do_trace *
36 *===========================================================================*/
37PUBLIC int do_trace()
38{
39 register struct mproc *child;
40 int r;
41
42 /* the T_OK call is made by the child fork of the debugger before it execs
43 * the process to be traced
44 */
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);
49 }
50 if ((child=find_proc(m_in.pid))==NIL_MPROC || !(child->mp_flags & STOPPED)) {
51 return(ESRCH);
52 }
53 /* all the other calls are made by the parent fork of the debugger to
54 * control execution of the child
55 */
56 switch (m_in.request) {
57 case T_EXIT: /* exit */
58 pm_exit(child, (int) m_in.data);
59 mp->mp_reply.reply_trace = 0;
60 return(OK);
61 case T_RESUME:
62 case T_STEP: /* resume execution */
63 if (m_in.data < 0 || m_in.data > _NSIG) return(EIO);
64 if (m_in.data > 0) { /* issue signal */
65 child->mp_flags &= ~TRACED; /* so signal is not diverted */
66 sig_proc(child, (int) m_in.data);
67 child->mp_flags |= TRACED;
68 }
69 child->mp_flags &= ~STOPPED;
70 break;
71 }
72 r= sys_trace(m_in.request,child->mp_endpoint,m_in.taddr,&m_in.data);
73 if (r != OK) return(r);
74
75 mp->mp_reply.reply_trace = m_in.data;
76 return(OK);
77}
78
79/*===========================================================================*
80 * find_proc *
81 *===========================================================================*/
82PRIVATE struct mproc *find_proc(lpid)
83pid_t lpid;
84{
85 register struct mproc *rmp;
86
87 for (rmp = &mproc[0]; rmp < &mproc[NR_PROCS]; rmp++)
88 if (rmp->mp_flags & IN_USE && rmp->mp_pid == lpid) return(rmp);
89 return(NIL_MPROC);
90}
91
92/*===========================================================================*
93 * stop_proc *
94 *===========================================================================*/
95PUBLIC void stop_proc(rmp, signo)
96register struct mproc *rmp;
97int signo;
98{
99/* A traced process got a signal so stop it. */
100
101 register struct mproc *rpmp = mproc + rmp->mp_parent;
102 int r;
103
104 r= sys_trace(-1, rmp->mp_endpoint, 0L, (long *) 0);
105 if (r != OK) panic("pm", "sys_trace failed", r);
106
107 rmp->mp_flags |= STOPPED;
108 if (rpmp->mp_flags & WAITING) {
109 rpmp->mp_flags &= ~WAITING; /* parent is no longer waiting */
110 rpmp->mp_reply.reply_res2 = 0177 | (signo << 8);
111 setreply(rmp->mp_parent, rmp->mp_pid);
112 } else {
113 rmp->mp_sigstatus = signo;
114 }
115 return;
116}
Note: See TracBrowser for help on using the repository browser.