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 }