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