1 /* This file handles the memory 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 "mm.h"
24 #include <sys/ptrace.h>
25 #include <signal.h>
26 #include "mproc.h"
27 #include "param.h"
28
29 #define NIL_MPROC ((struct mproc *) 0)
30
31 FORWARD _PROTOTYPE( struct mproc *findproc, (pid_t lpid) );
32
33 /*===========================================================================*
34 * do_trace *
35 *===========================================================================*/
36 PUBLIC int do_trace()
37 {
38 register struct mproc *child;
39
40 /* the T_OK call is made by the child fork of the debugger before it execs
41 * the process to be traced
42 */
43 if (request == T_OK) {/* enable tracing by parent for this process */
44 mp->mp_flags |= TRACED;
45 mm_out.m2_l2 = 0;
46 return(OK);
47 }
48 if ((child = findproc(pid)) == NIL_MPROC || !(child->mp_flags & STOPPED)) {
49 return(ESRCH);
50 }
51 /* all the other calls are made by the parent fork of the debugger to
52 * control execution of the child
53 */
54 switch (request) {
55 case T_EXIT: /* exit */
56 mm_exit(child, (int)data);
57 mm_out.m2_l2 = 0;
58 return(OK);
59 case T_RESUME:
60 case T_STEP: /* resume execution */
61 if (data < 0 || data > _NSIG) return(EIO);
62 if (data > 0) { /* issue signal */
63 child->mp_flags &= ~TRACED; /* so signal is not diverted */
64 sig_proc(child, (int) data);
65 child->mp_flags |= TRACED;
66 }
67 child->mp_flags &= ~STOPPED;
68 break;
69 }
70 if (sys_trace(request, (int) (child - mproc), taddr, &data) != OK)
71 return(-errno);
72 mm_out.m2_l2 = data;
73 return(OK);
74 }
75
76 /*===========================================================================*
77 * findproc *
78 *===========================================================================*/
79 PRIVATE struct mproc *findproc(lpid)
80 pid_t lpid;
81 {
82 register struct mproc *rmp;
83
84 for (rmp = &mproc[INIT_PROC_NR + 1]; rmp < &mproc[NR_PROCS]; rmp++)
85 if (rmp->mp_flags & IN_USE && rmp->mp_pid == lpid) return(rmp);
86 return(NIL_MPROC);
87 }
88
89 /*===========================================================================*
90 * stop_proc *
91 *===========================================================================*/
92 PUBLIC void stop_proc(rmp, signo)
93 register struct mproc *rmp;
94 int signo;
95 {
96 /* A traced process got a signal so stop it. */
97
98 register struct mproc *rpmp = mproc + rmp->mp_parent;
99
100 if (sys_trace(-1, (int) (rmp - mproc), 0L, (long *) 0) != OK) return;
101 rmp->mp_flags |= STOPPED;
102 if (rpmp->mp_flags & WAITING) {
103 rpmp->mp_flags &= ~WAITING; /* parent is no longer waiting */
104 reply(rmp->mp_parent, rmp->mp_pid, 0177 | (signo << 8), NIL_PTR);
105 } else {
106 rmp->mp_sigstatus = signo;
107 }
108 return;
109 }
110
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.