|
|
1.1 ! root 1: /* ! 2: * machine-specific functions for running the debugged process ! 3: * particular to VAX and /proc ! 4: */ ! 5: ! 6: #include "defs.h" ! 7: #include <sys/types.h> ! 8: #include <sys/pioctl.h> ! 9: #include <sys/vtimes.h> ! 10: #include <sys/proc.h> ! 11: #include <signal.h> ! 12: #include <sys/psl.h> ! 13: #include <errno.h> ! 14: #include "regs.h" ! 15: ! 16: MSG NOFORK; ! 17: MSG BADWAIT; ! 18: MSG ENDPCS; ! 19: ! 20: char lastc, peekc; ! 21: ADDR txtsize; ! 22: ! 23: static int child; ! 24: static long tsigs = -1; ! 25: ! 26: /* ! 27: * kill process ! 28: */ ! 29: ! 30: killpcs() ! 31: { ! 32: long sig = SIGKILL; ! 33: ! 34: ioctl(fcor, PIOCCSIG, 0); ! 35: ioctl(fcor, PIOCKILL, &sig); ! 36: ioctl(fcor, PIOCRUN, 0); ! 37: } ! 38: ! 39: /* ! 40: * grab the process already opened (but not traced); ! 41: * stop it so we can look at it ! 42: */ ! 43: ! 44: grab() ! 45: { ! 46: struct proc p; ! 47: int f; ! 48: ! 49: if ((f = open(corfil, 2)) < 0) ! 50: error("no write access"); ! 51: close(fcor); ! 52: fcor = f; ! 53: if (ioctl(fcor, PIOCGETPR, &p) < 0) ! 54: error("not a process"); ! 55: pid = p.p_pid; ! 56: child = 0; ! 57: ioctl(fcor, PIOCSMASK, &tsigs); ! 58: if (p.p_stat != SSTOP) ! 59: ioctl(fcor, PIOCSTOP, 0); ! 60: bpwait(); ! 61: } ! 62: ! 63: /* ! 64: * turn off tracing & let it go ! 65: */ ! 66: ! 67: ungrab() ! 68: { ! 69: long zero = 0; ! 70: ! 71: if (signo == 0) ! 72: ioctl(fcor, PIOCCSIG, 0); ! 73: ioctl(fcor, PIOCSMASK, &zero); ! 74: ioctl(fcor, PIOCRUN, 0); ! 75: pid = 0; ! 76: } ! 77: ! 78: /* ! 79: * get the program to be debugged ready to run ! 80: * program is left stopped at the beginning (so we can poke in breakpoints) ! 81: */ ! 82: ! 83: startpcs() ! 84: { ! 85: int fd; ! 86: char *procname(); ! 87: extern int (*sigint)(), (*sigqit)(); ! 88: ! 89: fd = procopen(getpid()); ! 90: if (ioctl(fd, PIOCSEXEC, 0) < 0) { ! 91: close(fd); ! 92: error("no process ioctl"); ! 93: } ! 94: if ((pid = fork()) == 0) { ! 95: close(fd); ! 96: close(fsym); ! 97: close(fcor); ! 98: signal(SIGINT, sigint); ! 99: signal(SIGQUIT, sigqit); ! 100: doexec(); ! 101: exit(0); ! 102: } ! 103: ioctl(fd, PIOCREXEC, 0); ! 104: close(fd); ! 105: if (pid == -1) ! 106: error(NOFORK); ! 107: child++; ! 108: fcor = procopen(pid); ! 109: corfil = procname(pid); ! 110: ioctl(fcor, PIOCSMASK, &tsigs); ! 111: bpwait(); ! 112: ioctl(fcor, PIOCREXEC, 0); ! 113: if (adrflg) ! 114: rput(PC, wtoa(adrval)); ! 115: while (rdc() != EOR) ! 116: ; ! 117: reread(); ! 118: } ! 119: ! 120: int ! 121: procopen(pid) ! 122: int pid; ! 123: { ! 124: char *pn; ! 125: int fd; ! 126: char *procname(); ! 127: ! 128: pn = procname(pid); ! 129: if ((fd = open(pn, 2)) < 0) { ! 130: printf("%s: cannot open\n", pn); ! 131: error(0); ! 132: } ! 133: return (fd); ! 134: } ! 135: ! 136: char * ! 137: procname(pid) ! 138: int pid; ! 139: { ! 140: static char name[20]; ! 141: ! 142: sprintf(name, "/proc/%d", pid); ! 143: return (name); ! 144: } ! 145: ! 146: /* ! 147: * set process running, single-stepped ! 148: */ ! 149: ! 150: runstep(keepsig) ! 151: int keepsig; ! 152: { ! 153: ! 154: delbp(); ! 155: rput(PSL, rget(PSL) | PSL_T); ! 156: rrest(); ! 157: if (keepsig == 0) ! 158: ioctl(fcor, PIOCCSIG, 0); ! 159: ioctl(fcor, PIOCRUN, 0); ! 160: } ! 161: ! 162: /* ! 163: * set process running ! 164: */ ! 165: ! 166: runrun(keepsig) ! 167: int keepsig; ! 168: { ! 169: ! 170: if (keepsig == 0) ! 171: ioctl(fcor, PIOCCSIG, 0); ! 172: ioctl(fcor, PIOCRUN, 0); ! 173: } ! 174: ! 175: /* ! 176: * exec the program to be debugged ! 177: * opening standard input and output as requested ! 178: */ ! 179: ! 180: doexec() ! 181: { ! 182: char *argl[MAXARG]; ! 183: char args[LINSIZ]; ! 184: register char *p; ! 185: register char **ap; ! 186: register char *thisarg; ! 187: extern char **environ; ! 188: ! 189: ap = argl; ! 190: p = args; ! 191: *ap++ = symfil; ! 192: for (rdc(); lastc != EOR;) { ! 193: thisarg = p; ! 194: while (lastc != EOR && lastc != SP && lastc != TB) { ! 195: *p++ = lastc; ! 196: readchar(); ! 197: } ! 198: if (lastc == SP || lastc == TB) ! 199: rdc(); ! 200: *p++ = 0; ! 201: if (*thisarg == '<') { ! 202: close(0); ! 203: if (open(&thisarg[1], 0) < 0) { ! 204: printf("%s: cannot open\n", &thisarg[1]); ! 205: _exit(0); ! 206: } ! 207: } ! 208: else if (*thisarg == '>') { ! 209: close(1); ! 210: if (creat(&thisarg[1], 0666) < 0) { ! 211: printf("%s: cannot create\n", &thisarg[1]); ! 212: _exit(0); ! 213: } ! 214: } ! 215: else ! 216: *ap++ = thisarg; ! 217: } ! 218: *ap = NULL; ! 219: execve(symfil, argl, environ); ! 220: perror(symfil); ! 221: } ! 222: ! 223: /* ! 224: * install (f != 0) or remove (f == 0) a breakpoint ! 225: */ ! 226: ! 227: #define BPT 03 ! 228: ! 229: bkput(bk, f) ! 230: register BKPT *bk; ! 231: { ! 232: register int sp; ! 233: ! 234: if (bk->loc < txtsize) ! 235: sp = CORF | INSTSP; ! 236: else ! 237: sp = CORF | DATASP; ! 238: if (f == 0) ! 239: cput(bk->loc, sp, wtoc(bk->ins)); ! 240: else { ! 241: bk->ins = ctow(cget(bk->loc, sp)); ! 242: cput(bk->loc, sp, wtoc(BPT)); ! 243: if (errflg) { ! 244: printf("cannot set breakpoint: "); ! 245: /* stuff */ ! 246: prints(errflg); ! 247: } ! 248: } ! 249: } ! 250: ! 251: /* ! 252: * wait for the process to stop; ! 253: * pick up status and registers when it does ! 254: */ ! 255: ! 256: #define WSLEEP 10 ! 257: ! 258: bpwait() ! 259: { ! 260: register int w; ! 261: int stat; ! 262: int (*isig)(); ! 263: int nulsig(); ! 264: extern int errno; ! 265: ! 266: isig = signal(SIGINT, SIG_IGN); ! 267: /* ! 268: * alarm stuff is just in case ! 269: */ ! 270: for (;;) { ! 271: signal(SIGALRM, nulsig); ! 272: alarm(WSLEEP); ! 273: if (ioctl(fcor, PIOCWSTOP, 0) >= 0) ! 274: errno = 0; ! 275: alarm(0); ! 276: if (errno == 0) { ! 277: signal(SIGINT, isig); ! 278: mapimage(); ! 279: if (signo == SIGTRAP || signo == SIGSTOP) ! 280: signo = 0; ! 281: else { ! 282: sigprint(); ! 283: newline(); ! 284: } ! 285: return; /* should set stuff? */ ! 286: } ! 287: if (errno == ENOENT) ! 288: break; ! 289: /* still there, still running. try again. */ ! 290: } ! 291: if (child == 0) { ! 292: close(fcor); ! 293: pid = 0; ! 294: corfil = NULL; ! 295: errflg = ENDPCS; ! 296: return; ! 297: } ! 298: /* ! 299: * process has died; wait and report status ! 300: * should check if it's really our child ! 301: */ ! 302: signal(SIGALRM, nulsig); ! 303: alarm(WSLEEP); ! 304: while ((w = wait(&stat)) != -1 && w != pid) ! 305: ; ! 306: alarm(0); ! 307: pid = 0; ! 308: signal(SIGINT, isig); ! 309: close(fcor); ! 310: pid = 0; ! 311: corfil = NULL; ! 312: errflg = ENDPCS; ! 313: if (w == -1) ! 314: errflg = BADWAIT; ! 315: else { ! 316: if ((stat & 0177) == 0177) ! 317: printf("trace status? 0%o\n", stat); ! 318: else { ! 319: sigcode = 0; ! 320: if ((signo = stat & 0177) != 0) ! 321: sigprint(); ! 322: if (stat & 0200) { ! 323: prints(" - core dumped"); ! 324: corfil = "core"; ! 325: setcor(); ! 326: } ! 327: } ! 328: } ! 329: } ! 330: ! 331: static ! 332: nulsig() ! 333: { ! 334: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.