xref: /plan9/sys/src/cmd/db/pcs.c (revision 9a747e4fd48b9f4522c70c07e8f882a15030f964)
1 /*
2  *
3  *	debugger
4  *
5  */
6 
7 #include "defs.h"
8 #include "fns.h"
9 
10 char	NOPCS[] = "no process";
11 
12 /* sub process control */
13 
14 void
subpcs(int modif)15 subpcs(int modif)
16 {
17 	int	check;
18 	int	runmode;
19 	int	keepnote;
20 	int	n, r;
21 	long line, curr;
22 	BKPT *bk;
23 	char *comptr;
24 
25 	runmode=SINGLE;
26 	r = 0;
27 	keepnote=0;
28 	loopcnt=cntval;
29 	switch (modif) {
30 
31 		/* delete breakpoint */
32 	case 'd':
33 	case 'D':
34 		if ((bk=scanbkpt(dot)) == 0)
35 			error("no breakpoint set");
36 		bk->flag=BKPTCLR;
37 		return;
38 
39 		/* set breakpoint */
40 	case 'b':
41 	case 'B':
42 		if (bk=scanbkpt(dot))
43 			bk->flag=BKPTCLR;
44 		for (bk=bkpthead; bk; bk=bk->nxtbkpt)
45 			if (bk->flag == BKPTCLR)
46 				break;
47 		if (bk==0) {
48 			bk = (BKPT *)malloc(sizeof(*bk));
49 			if (bk == 0)
50 				error("too many breakpoints");
51 			bk->nxtbkpt=bkpthead;
52 			bkpthead=bk;
53 		}
54 		bk->loc = dot;
55 		bk->initcnt = bk->count = cntval;
56 		bk->flag = modif == 'b' ? BKPTSET : BKPTTMP;
57 		check=MAXCOM-1;
58 		comptr=bk->comm;
59 		rdc();
60 		reread();
61 		do {
62 			*comptr++ = readchar();
63 		} while (check-- && lastc!=EOR);
64 		*comptr=0;
65 		if(bk->comm[0] != EOR && cntflg == FALSE)
66 			bk->initcnt = bk->count = HUGEINT;
67 		reread();
68 		if (check)
69 			return;
70 		error("bkpt command too long");
71 
72 		/* exit */
73 	case 'k' :
74 	case 'K':
75 		if (pid == 0)
76 			error(NOPCS);
77 		dprint("%d: killed", pid);
78 		pcsactive = 1;	/* force 'kill' ctl */
79 		endpcs();
80 		return;
81 
82 		/* run program */
83 	case 'r':
84 	case 'R':
85 		endpcs();
86 		setup();
87 		runmode = CONTIN;
88 		break;
89 
90 		/* single step */
91 	case 's':
92 		if (pid == 0) {
93 			setup();
94 			loopcnt--;
95 		}
96 		runmode=SINGLE;
97 		keepnote=defval(1);
98 		break;
99 	case 'S':
100 		if (pid == 0) {
101 			setup();
102 			loopcnt--;
103 		}
104 		keepnote=defval(1);
105 		line = pc2line(rget(cormap, mach->pc));
106 		n = loopcnt;
107 		dprint("%s: running\n", symfil);
108 		flush();
109 		for (loopcnt = 1; n > 0; loopcnt = 1) {
110 			r = runpcs(SINGLE, keepnote);
111 			curr = pc2line(dot);
112 			if (line != curr) {	/* on a new line of c */
113 				line = curr;
114 				n--;
115 			}
116 		}
117 		loopcnt = 0;
118 		break;
119 		/* continue with optional note */
120 	case 'c':
121 	case 'C':
122 		if (pid==0)
123 			error(NOPCS);
124 		runmode=CONTIN;
125 		keepnote=defval(1);
126 		break;
127 
128 	case 'n':	/* deal with notes */
129 		if (pid==0)
130 			error(NOPCS);
131 		n=defval(-1);
132 		if(n>=0 && n<nnote){
133 			nnote--;
134 			memmove(note[n], note[n+1], (nnote-n)*sizeof(note[0]));
135 		}
136 		notes();
137 		return;
138 
139 	case 'h':	/* halt the current process */
140 		if (adrflg && adrval == 0) {
141 			if (pid == 0)
142 				error(NOPCS);
143 			ungrab();
144 		}
145 		else {
146 			grab();
147 			dprint("stopped at%16t");
148 			goto Return;
149 		}
150 		return;
151 
152 	case 'x':	/* continue executing the current process */
153 		if (pid == 0)
154 			error(NOPCS);
155 		ungrab();
156 		return;
157 
158 	default:
159 		error("bad `:' command");
160 	}
161 
162 	if (loopcnt>0) {
163 		dprint("%s: running\n", symfil);
164 		flush();
165 		r = runpcs(runmode,keepnote);
166 	}
167 	if (r)
168 		dprint("breakpoint%16t");
169 	else
170 		dprint("stopped at%16t");
171     Return:
172 	delbp();
173 	printpc();
174 	notes();
175 }
176