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