plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

trcrun.c (4406B)


      1 /*
      2  * functions for running the debugged process
      3  */
      4 
      5 #include "defs.h"
      6 #include "fns.h"
      7 
      8 
      9 int child;
     10 int msgfd = -1;
     11 int notefd = -1;
     12 int pcspid = -1;
     13 int pcsactive = 0;
     14 
     15 void
     16 setpcs(void)
     17 {
     18 	char buf[128];
     19 
     20 	if(pid && pid != pcspid){
     21 		if(msgfd >= 0){
     22 			close(msgfd);
     23 			msgfd = -1;
     24 		}
     25 		if(notefd >= 0){
     26 			close(notefd);
     27 			notefd = -1;
     28 		}
     29 		pcspid = -1;
     30 		sprint(buf, "/proc/%d/ctl", pid);
     31 		msgfd = open(buf, OWRITE);
     32 		if(msgfd < 0)
     33 			error("can't open control file");
     34 		sprint(buf, "/proc/%d/note", pid);
     35 		notefd = open(buf, ORDWR);
     36 		if(notefd < 0)
     37 			error("can't open note file");
     38 		pcspid = pid;
     39 	}
     40 }
     41 
     42 void
     43 msgpcs(char *msg)
     44 {
     45 	char err[ERRMAX];
     46 
     47 	setpcs();
     48 	if(write(msgfd, msg, strlen(msg)) < 0 && !ending){
     49 		errstr(err, sizeof err);
     50 		if(strcmp(err, "interrupted") != 0)
     51 			endpcs();
     52 		errors("can't write control file", err);
     53 	}
     54 }
     55 
     56 /*
     57  * empty the note buffer and toss pending breakpoint notes
     58  */
     59 void
     60 unloadnote(void)
     61 {
     62 	char err[ERRMAX];
     63 
     64 	setpcs();
     65 	for(; nnote<NNOTE; nnote++){
     66 		switch(read(notefd, note[nnote], sizeof note[nnote])){
     67 		case -1:
     68 			errstr(err, sizeof err);
     69 			if(strcmp(err, "interrupted") != 0)
     70 				endpcs();
     71 			errors("can't read note file", err);
     72 		case 0:
     73 			return;
     74 		}
     75 		note[nnote][ERRMAX-1] = '\0';
     76 		if(strncmp(note[nnote], "sys: breakpoint", 15) == 0)
     77 			--nnote;
     78 	}
     79 }
     80 
     81 /*
     82  * reload the note buffer
     83  */
     84 void
     85 loadnote(void)
     86 {
     87 	int i;
     88 	char err[ERRMAX];
     89 
     90 	setpcs();
     91 	for(i=0; i<nnote; i++){
     92 		if(write(notefd, note[i], strlen(note[i])) < 0){
     93 			errstr(err, sizeof err);
     94 			if(strcmp(err, "interrupted") != 0)
     95 				endpcs();
     96 			errors("can't write note file", err);
     97 		}
     98 	}
     99 	nnote = 0;
    100 }
    101 
    102 void
    103 notes(void)
    104 {
    105 	int n;
    106 
    107 	if(nnote == 0)
    108 		return;
    109 	dprint("notes:\n");
    110 	for(n=0; n<nnote; n++)
    111 		dprint("%d:\t%s\n", n, note[n]);
    112 }
    113 
    114 void
    115 killpcs(void)
    116 {
    117 	msgpcs("kill");
    118 }
    119 
    120 void
    121 grab(void)
    122 {
    123 	flush();
    124 	msgpcs("stop");
    125 	bpwait();
    126 }
    127 
    128 void
    129 ungrab(void)
    130 {
    131 	msgpcs("start");
    132 }
    133 
    134 void
    135 doexec(void)
    136 {
    137 	char *argl[MAXARG];
    138 	char args[LINSIZ];
    139 	char *p;
    140 	char **ap;
    141 	char *thisarg;
    142 
    143 	ap = argl;
    144 	p = args;
    145 	*ap++ = symfil;
    146 	for (rdc(); lastc != EOR;) {
    147 		thisarg = p;
    148 		if (lastc == '<' || lastc == '>') {
    149 			*p++ = lastc;
    150 			rdc();
    151 		}
    152 		while (lastc != EOR && lastc != SPC && lastc != TB) {
    153 			*p++ = lastc;
    154 			readchar();
    155 		}
    156 		if (lastc == SPC || lastc == TB)
    157 			rdc();
    158 		*p++ = 0;
    159 		if (*thisarg == '<') {
    160 			close(0);
    161 			if (open(&thisarg[1], OREAD) < 0) {
    162 				print("%s: cannot open\n", &thisarg[1]);
    163 				_exits(0);
    164 			}
    165 		}
    166 		else if (*thisarg == '>') {
    167 			close(1);
    168 			if (create(&thisarg[1], OWRITE, 0666) < 0) {
    169 				print("%s: cannot create\n", &thisarg[1]);
    170 				_exits(0);
    171 			}
    172 		}
    173 		else
    174 			*ap++ = thisarg;
    175 	}
    176 	*ap = 0;
    177 	exec(symfil, argl);
    178 	perror(symfil);
    179 }
    180 
    181 char	procname[100];
    182 
    183 void
    184 startpcs(void)
    185 {
    186 	if ((pid = fork()) == 0) {
    187 		pid = getpid();
    188 		msgpcs("hang");
    189 		doexec();
    190 		exits(0);
    191 	}
    192 
    193 	if (pid == -1)
    194 		error("can't fork");
    195 	child++;
    196 	sprint(procname, "/proc/%d/mem", pid);
    197 	corfil = procname;
    198 	msgpcs("waitstop");
    199 	bpwait();
    200 	if (adrflg)
    201 		rput(correg, mach->pc, adrval);
    202 	while (rdc() != EOR)
    203 		;
    204 	reread();
    205 }
    206 
    207 void
    208 runstep(ulong loc, int keepnote)
    209 {
    210 	int nfoll;
    211 	ADDR foll[3];
    212 	BKPT bkpt[3];
    213 	int i;
    214 
    215 	if(mach->foll == 0){
    216 		dprint("stepping unimplemented; assuming not a branch\n");
    217 		nfoll = 1;
    218 		foll[0] = loc+mach->pcquant;
    219 	}else {
    220 		nfoll = mach->foll(cormap, correg, loc, foll);
    221 		if (nfoll < 0)
    222 			error("%r");
    223 	}
    224 	memset(bkpt, 0, sizeof bkpt);
    225 	for(i=0; i<nfoll; i++){
    226 		if(foll[i] == loc)
    227 			error("can't single step: next instruction is dot");
    228 		bkpt[i].loc = foll[i];
    229 		bkput(&bkpt[i], 1);
    230 	}
    231 	runrun(keepnote);
    232 	for(i=0; i<nfoll; i++)
    233 		bkput(&bkpt[i], 0);
    234 }
    235 
    236 void
    237 bpwait(void)
    238 {
    239 	setcor();
    240 	unloadnote();
    241 }
    242 
    243 void
    244 runrun(int keepnote)
    245 {
    246 	int on;
    247 
    248 	on = nnote;
    249 	unloadnote();
    250 	if(on != nnote){
    251 		notes();
    252 		error("not running: new notes pending");
    253 	}
    254 	if(keepnote)
    255 		loadnote();
    256 	else
    257 		nnote = 0;
    258 	flush();
    259 	msgpcs("startstop");
    260 	bpwait();
    261 }
    262 
    263 void
    264 bkput(BKPT *bp, int install)
    265 {
    266 	char buf[256];
    267 	ulong loc;
    268 	int ret;
    269 
    270 	errstr(buf, sizeof buf);
    271 /*
    272 	if(mach->bpfix)
    273 		loc = (*mach->bpfix)(bp->loc);
    274 	else
    275 */
    276 	loc = bp->loc;
    277 	if(install){
    278 		ret = get1(cormap, loc, bp->save, mach->bpsize);
    279 		if (ret > 0)
    280 			ret = put1(cormap, loc, mach->bpinst, mach->bpsize);
    281 	}else
    282 		ret = put1(cormap, loc, bp->save, mach->bpsize);
    283 	if(ret < 0){
    284 		sprint(buf, "can't set breakpoint at %#llux: %r", bp->loc);
    285 		print(buf);
    286 		read(0, buf, 100);
    287 	}
    288 }