|
|
1.1 ! root 1: static char sccsid[] = "@(#)pt.c 2.10"; ! 2: ! 3: #include <errno.h> ! 4: #include <signal.h> ! 5: ! 6: #ifndef REGULUS ! 7: #include <sys/param.h> ! 8: #endif ! 9: #ifdef SUN ! 10: #define SYSTYPES 1 /* see basic.h */ ! 11: #endif ! 12: #ifdef SYSIII ! 13: #define SYSTYPES 1 /* see basic.h */ ! 14: #endif ! 15: #include "cdb.h" ! 16: #include "macdefs.h" ! 17: ! 18: #ifdef SYSIII ! 19: #include <termio.h> ! 20: #ifdef REGULUS ! 21: /* remove the two TCxxxxx and ! 22: * add #include <sys/ioctl.h> when preporocessor is fixed ! 23: */ ! 24: #define TCGETA 1 ! 25: #define TCSETAW 3 ! 26: #define EINTR -1 ! 27: #endif ! 28: struct termio histty, mytty; ! 29: #endif ! 30: ! 31: #ifdef BSD41 ! 32: #include <sgtty.h> ! 33: struct sgttyb histty, mytty; ! 34: #endif ! 35: ! 36: export int vibp; /* last breakpoint hit, if any */ ! 37: ! 38: export uint vsig; ! 39: uint vstat, vstatHi, vstatLo; ! 40: SAR vmpSigSa[NSIG]; /* signal action array */ ! 41: ! 42: void Fixer(); ! 43: ! 44: #define cArgsMax 30 ! 45: char *argvChild[cArgsMax]; ! 46: #define cbArgsMax 200 ! 47: export char vsbArgsChild[cbArgsMax]; /* where we store args for child */ ! 48: ! 49: ! 50: /* N E X T A R G */ ! 51: ! 52: export char * NextArg(psbIn) ! 53: char **psbIn; ! 54: { ! 55: char *sbRet; ! 56: ! 57: /* skip white space */ ! 58: while (**psbIn == ' ' OR **psbIn == '\t') ! 59: (*psbIn)++; ! 60: if (**psbIn == chNull) ! 61: return(sbNil); /* that's all, folks! */ ! 62: sbRet = *psbIn; /* set current arg pointer */ ! 63: while (**psbIn != chNull ! 64: AND **psbIn != ' ' ! 65: AND **psbIn != '\t') ! 66: (*psbIn)++; /* skip all non-white space characters */ ! 67: **psbIn = chNull; /* overwrite the tab, space, or 0 with a 0 */ ! 68: (*psbIn)++; ! 69: return(sbRet); ! 70: } /* NextArg */ ! 71: ! 72: ! 73: /* D O A R G S */ ! 74: ! 75: export void DoArgs(sbProgram, sbArgs, argv, fReassign) ! 76: char *sbProgram, *sbArgs; ! 77: char **argv; ! 78: FLAGT fReassign; ! 79: { ! 80: int i; ! 81: char *sbFile, *sbArgCur; ! 82: ! 83: for (i=0; i< cArgsMax; i++) ! 84: argv[i] = sbNil; ! 85: ! 86: *argv++ = sbProgram; /* set the filename */ ! 87: ! 88: /* eat the arguments */ ! 89: while ((sbArgs != sbNil) ! 90: AND (*sbArgs != chNull)) { ! 91: sbArgCur = NextArg(&sbArgs); ! 92: if (sbArgCur == sbNil) ! 93: break; ! 94: /* check for indirection */ ! 95: if (!fReassign ! 96: OR ((*sbArgCur != '<') AND (*sbArgCur != '>')) ) { ! 97: *argv++ = sbArgCur; /* we just pass it on */ ! 98: } ! 99: else { ! 100: /* find that file name */ ! 101: sbFile = sbArgCur + 1; /* initially we assume `<foo' vs `< foo' */ ! 102: if (*sbFile == chNull) { ! 103: /* there was white space between < and sbFile */ ! 104: sbFile = NextArg(&sbArgs); ! 105: if (sbFile == sbNil) { ! 106: printf("Illegal indirection\n"); ! 107: exit(1); ! 108: } /* if */ ! 109: } /* if */ ! 110: if (*sbArgCur == '<') { ! 111: /* changing stdin */ ! 112: close(0); ! 113: if (open(sbFile, O_RDONLY) < 0) { ! 114: perror(sbFile); ! 115: exit(1); ! 116: } /* if */ ! 117: } ! 118: else if (*sbArgCur == '>') { ! 119: /* changing stdout */ ! 120: close(1); ! 121: if (creat(sbFile, 0666) < 0) { ! 122: perror(sbFile); ! 123: exit(1); ! 124: } /* if */ ! 125: } /* if */ ! 126: } /* if */ ! 127: } /* while */ ! 128: *argv = sbNil; ! 129: } /* DoArgs */ ! 130: ! 131: ! 132: /* P R I N T S I G */ ! 133: ! 134: export void PrintSig(sig) ! 135: int sig; ! 136: { ! 137: switch (sig) { ! 138: case SIGHUP: ! 139: printf("Hangup"); ! 140: break; ! 141: case SIGINT: ! 142: printf("interrupt"); ! 143: break; ! 144: case SIGQUIT: ! 145: printf("quit"); ! 146: break; ! 147: case SIGILL: ! 148: printf("illegal instruction"); ! 149: break; ! 150: case SIGTRAP: ! 151: printf("breakpoint"); ! 152: break; ! 153: case SIGIOT: ! 154: printf("IOT instruction"); ! 155: break; ! 156: case SIGEMT: ! 157: printf("EMT instruction"); ! 158: break; ! 159: case SIGFPE: ! 160: printf("floating point exception"); ! 161: break; ! 162: case SIGKILL: ! 163: printf("kill"); ! 164: break; ! 165: case SIGBUS: ! 166: printf("bus error"); ! 167: break; ! 168: case SIGSEGV: ! 169: printf("segmentaion violation"); ! 170: break; ! 171: case SIGSYS: ! 172: printf("bad arg to sys call"); ! 173: break; ! 174: case SIGPIPE: ! 175: printf("write on pipe with no reader"); ! 176: break; ! 177: case SIGALRM: ! 178: printf("alarm clock"); ! 179: break; ! 180: case SIGTERM: ! 181: printf("software termination"); ! 182: break; ! 183: #ifdef SYSIII ! 184: case SIGUSR1: ! 185: printf("user signal 1"); ! 186: break; ! 187: case SIGUSR2: ! 188: printf("user signal 2"); ! 189: break; ! 190: case SIGCLD: ! 191: printf("death of child"); ! 192: break; ! 193: case SIGPWR: ! 194: printf("power fail"); ! 195: break; ! 196: #endif ! 197: #ifdef BSD41 ! 198: #ifdef BSD42 ! 199: case SIGURG: ! 200: printf("urgent condition on IO channel"); ! 201: break; ! 202: case SIGIO: ! 203: printf("input/output possible signal"); ! 204: break; ! 205: case SIGVTALRM: ! 206: printf("virtual time alarm"); ! 207: break; ! 208: case SIGPROF: ! 209: printf("profiling time alarm"); ! 210: break; ! 211: #endif ! 212: case SIGSTOP: ! 213: printf("sendable stop signal not from tty"); ! 214: break; ! 215: case SIGTSTP: ! 216: printf("stop signal from tty"); ! 217: break; ! 218: case SIGCONT: ! 219: printf("attempt to continue a stopped process"); ! 220: break; ! 221: case SIGCHLD: ! 222: printf("child stop or exit"); ! 223: break; ! 224: case SIGTTIN: ! 225: printf("to readers pgrp upon background tty read"); ! 226: break; ! 227: case SIGTTOU: ! 228: printf("to writers pgrp upon background tty write"); ! 229: break; ! 230: case SIGXCPU: ! 231: printf("exceeded CPU time limit"); ! 232: break; ! 233: case SIGXFSZ: ! 234: printf("exceeded file size limit"); ! 235: break; ! 236: #endif ! 237: default: ! 238: printf("signal %d", sig); ! 239: break; ! 240: } /* switch */ ! 241: } /* PrintSig */ ! 242: ! 243: ! 244: /* I B P F W A I T */ ! 245: ! 246: export int IbpFWait(fDoBrk) ! 247: FLAGT fDoBrk; ! 248: { ! 249: int ibp, waitReturn; ! 250: pSAR sa; ! 251: ! 252: keepGoing: /* we come here if the signal is not interesting */ ! 253: ! 254: signal(SIGINT, SIG_IGN); /* ignore INT - let child deal with it */ ! 255: ! 256: while ( ((waitReturn=wait(&vstat)) != vpid) AND (waitReturn != -1) ) ! 257: ; ! 258: ! 259: #ifdef SYSIII ! 260: ioctl(0, TCGETA, &histty); /* save his state, restore my state */ ! 261: ioctl(0, TCSETAW, &mytty); ! 262: #endif ! 263: #ifdef BSD41 ! 264: gtty(0, &histty); /* save his state, restore my state */ ! 265: stty(0, &mytty); ! 266: #endif ! 267: signal(SIGINT, Fixer); /* reconnect to the Fixer routine */ ! 268: ! 269: GetState(); ! 270: ! 271: vsig = vstatHi = vstat >> 8; ! 272: vstatLo = vstat & 0377; ! 273: vibp = ibp = ibpNil; /* index of the breakpoint we are at (if any) */ ! 274: if (waitReturn == -1) { ! 275: if (errno == EINTR) { ! 276: printf("PANIC! received signal: %d????\n", vsig); ! 277: /* what do we do here?? */ ! 278: exit(1); ! 279: } ! 280: else { /* some sort of error occurred */ ! 281: perror("cdb"); ! 282: exit(1); ! 283: } /* if */ ! 284: } ! 285: else if (vstatLo == 0) { /* child terminated */ ! 286: if (vstatHi != 0) ! 287: printf("Process exited with %d\n", vstatHi); ! 288: else printf("Process terminated normally\n"); ! 289: KillChild(); /* go bury the corpse */ ! 290: ibp = 0; /* small hack - causes single step to stop in cmd.c */ ! 291: } ! 292: else if ((vstatLo&0177) == 0177) { /* child stopped */ ! 293: sa = vmpSigSa + vsig; ! 294: if (sa->fNoStop) { ! 295: #ifdef SYSIII ! 296: ioctl(0, TCSETAW, &histty); ! 297: #endif ! 298: #ifdef BSD41 ! 299: stty(0, &histty); ! 300: #endif ! 301: if (!(sa->fNoReport)) { ! 302: PrintSig(vsig); ! 303: printf(" at %s\n", SbFAdr(lengthen(vpc), true)); ! 304: PrintPos(vpc, fmtProc+fmtLn+fmtPrint); ! 305: } /* if */ ! 306: vsig = (sa->fEatSig) ? 0 : vsig; ! 307: ptrace(ptResume, vpid, 1, vsig); /* continue */ ! 308: goto keepGoing; ! 309: } /* if */ ! 310: /* NOTE: BrkOut MIGHT back up pc, depends on machine and instruction */ ! 311: vibp = ibp = (fDoBrk) ? BrkOut(&vpc) : ibpNil; ! 312: if (vpc == vadrBreak) { ! 313: /* we have hit the BP used for proc calls from command line */ ! 314: return(ibp); ! 315: } /* if */ ! 316: if ( (ibp >= 0) ! 317: AND (vrgBp[ibp].sbBp[0] != chNull) ) { ! 318: PushCmd(vsbCmd); ! 319: vsbCmd = vrgBp[ibp].sbBp; ! 320: } /* if */ ! 321: if ( (vsig != SIGTRAP) /* we ALWAYS report non-break signals */ ! 322: OR ((ibp >= 0) /* there is something to hear */ ! 323: AND (*vsbCmd != 'Q')) ) { /* and BP's want's it heard */ ! 324: printf("\n"); /* in case we were left in the middle of a line */ ! 325: PrintSig(vsig); ! 326: printf(" at %s\n", SbFAdr(lengthen(vpc), true)); ! 327: PrintPos(vpc, fmtProc+fmtLn+fmtPrint); ! 328: } ! 329: else if ((vsbCmd != sbNil) AND (*vsbCmd == 'Q')) { ! 330: PrintPos(vpc, fmtNil); ! 331: } /* if */ ! 332: vsig = (sa->fEatSig) ? 0 : vsig; ! 333: } ! 334: else if ((vstat & 0177) != 0177) { /* terminated on signal */ ! 335: if (vstat & 0177) ! 336: PrintSig(vstat&0177); ! 337: if (vstat & 0200) { ! 338: printf(" (core dumped)"); ! 339: close(vfnCore); ! 340: InitCorefile("core"); ! 341: } /* if */ ! 342: printf(" at %s\n", SbFAdr(lengthen(vpc), true)); ! 343: PrintPos(vpc, fmtProc+fmtLn+fmtPrint); ! 344: vpid = pidNil; ! 345: } /* if */ ! 346: return(ibp); ! 347: } /* IbpFWait */ ! 348: ! 349: ! 350: /* I B P F R U N */ ! 351: ! 352: export int IbpFRun(pt) ! 353: int pt; ! 354: { ! 355: int ibp; ! 356: ADRT pcOld; ! 357: ! 358: if (vpid == pidNil) ! 359: UError("No process"); ! 360: ! 361: if ((vfRunAssert) ! 362: AND (vas == asActive) ! 363: AND (viadMac > 0) ! 364: AND (pt != ptSingle)) { ! 365: /* do the assertions */ ! 366: if (FDoAssert(pt)) /* this will change vas and single step the child */ ! 367: return(ibpNil); /* an assertion came up true */ ! 368: if (vpid == pidNil) ! 369: return(ibpNil); /* the child died during assertions */ ! 370: if (vibp != ibpNil) ! 371: return(vibp); ! 372: } /* if */ ! 373: ! 374: /* hit the GO button */ ! 375: ! 376: do { /* loop allows for bp's that say 'continue' */ ! 377: /* if we are at a breakpoint, single step over it, then install it */ ! 378: if (IbpFBrkIn(vpc) != ibpNil) { ! 379: PutState(); ! 380: pcOld = vpc; ! 381: while (pcOld == vpc) { ! 382: ptrace(ptSingle, vpid, 1, vsig); ! 383: ibp = IbpFWait(false); ! 384: } /* while */ ! 385: if (pt == ptSingle) ! 386: return(ibp); /* we have already single stepped it for them */ ! 387: /* full steam ahead */ ! 388: IbpFBrkIn(adrNil); /* put in bp's */ ! 389: } /* if */ ! 390: ! 391: PutState(); ! 392: #ifdef SYSIII ! 393: ioctl(0, TCSETAW, &histty); ! 394: #endif ! 395: #ifdef BSD41 ! 396: stty(0, &histty); ! 397: #endif ! 398: errno = 0; ! 399: ptrace(pt, vpid, 1, vsig); /* start child with signal `sig' */ ! 400: ibp = IbpFWait(true); ! 401: } ! 402: while (ibp == ibpContinue); ! 403: return(ibp); ! 404: } /* IbpFRun */ ! 405: ! 406: ! 407: /* I B P F N E W C H I L D */ ! 408: ! 409: export int IbpFNewChild(sbArgs) ! 410: char *sbArgs; ! 411: { ! 412: int sig, i, ibp; ! 413: FLAGT fMaster; ! 414: ! 415: KillChild(); /* in case there is already one out there */ ! 416: ! 417: #ifdef SYSIII ! 418: ioctl(0, TCGETA, &histty); /* to start with, he is the same as me */ ! 419: ioctl(0, TCGETA, &mytty); /* save my stuff */ ! 420: #endif ! 421: #ifdef BSD41 ! 422: gtty(0, &histty); /* to start with, he is the same as me */ ! 423: gtty(0, &mytty); /* save my stuff */ ! 424: #endif ! 425: ! 426: if (sbArgs == sbNil) { ! 427: *vsbArgsChild = chNull; /* this comes from the R command */ ! 428: } ! 429: else { ! 430: fMaster = (sbArgs == vsbCmd); /* this is the normal command line */ ! 431: while (*sbArgs == ' ' OR *sbArgs == '\011') ! 432: sbArgs++; /* eat leading white space */ ! 433: if (*sbArgs != chNull) { ! 434: strcpy(vsbArgsChild, sbArgs); ! 435: for (i=strlen(sbArgs); i<cbArgsMax; i++) ! 436: vsbArgsChild[i] = chNull; ! 437: /* fixes obscure bug, don't ask why...... */ ! 438: if (fMaster) { ! 439: /* eat it - this way we don't ! 440: * try to execute the arguments to the child ! 441: * as debugger commands ! 442: */ ! 443: vsbCmd = sbNil; ! 444: } /* if */ ! 445: } /* if */ ! 446: } /* if */ ! 447: ! 448: close(vfnSym); /* in case it is PURE or SPLIT I&D */ ! 449: if ((vpid = fork()) == 0) { ! 450: for (sig=1; sig<NSIG; sig++) ! 451: signal(sig, SIG_DFL); /* start out with default response */ ! 452: DoArgs(vsbSymfile, vsbArgsChild, argvChild, true); ! 453: ptrace(ptChild, 0, 0, 0); /* Hi, Mom! */ ! 454: #ifdef REGULUS ! 455: #define flags 04+010+020 /* overlay + set trace + environment present */ ! 456: maketask(vsbSymfile, flags, 0, argvChild, venvpParent); ! 457: #else ! 458: execvp(vsbSymfile, argvChild); ! 459: #endif ! 460: /* if we get here, exec failed */ ! 461: perror("could not startup"); ! 462: exit(1); ! 463: } /* if */ ! 464: ! 465: /* should only get here if parent */ ! 466: printf("running '%s %s'\n", vsbSymfile, vsbArgsChild); ! 467: IbpFWait(false); ! 468: /* it is now safe to open symfile again */ ! 469: /* printf("Opening file %s\n", vsbSymfile); */ ! 470: vfnSym = open(vsbSymfile, O_RDONLY); ! 471: if (vfnSym < 0) { ! 472: perror(vsbSymfile); ! 473: exit(1); ! 474: } /* if */ ! 475: IbpFAdr(vadrStart, 0, sbNil); /* at first instruction */ ! 476: vfRunAssert = false; /* we don't want assertions during initialization */ ! 477: ibp = IbpFRun(ptResume); ! 478: vfRunAssert = true; ! 479: return(ibp); ! 480: } /* IbpFNewChild */ ! 481: ! 482: ! 483: /* K I L L C H I L D */ ! 484: ! 485: export void KillChild() ! 486: { ! 487: if (vpid != pidNil) { ! 488: ptrace(ptTerm, vpid, 0, 0); ! 489: } ! 490: vpid = pidNil; ! 491: vpc = adrNil; ! 492: vsig = 0; ! 493: vfp = 0; ! 494: if(vfnCore != fnNil) { ! 495: GetState(); /* refresh from the core file */ ! 496: vpc -= 2; /* so we have true address of error */ ! 497: } /* if */ ! 498: } /* KillChild */ ! 499: ! 500: ! 501: /* G O T O L N */ ! 502: ! 503: export void GotoLn(ln) ! 504: int ln; ! 505: { ! 506: ADRT adr; ! 507: ! 508: adr = AdrFIfdLn(vifd, ln); ! 509: if (IpdFAdr(adr) != IpdFAdr(vpc)) ! 510: UError("You can't goto a line outside of the current procedure"); ! 511: ! 512: /* if I can figure it out, it would be nice to be able to unwind the ! 513: * stack. We can get the pc, fp, and ap, but the sp seems to be unknown, ! 514: * plus the old register values. We might be able to 'goto' each ! 515: * procedure end, return up the stack, and keep doing that until we ! 516: * get there, but this is involved. Maybe if someone asks REAL nicely.... ! 517: */ ! 518: PutReg(upc, adr); ! 519: } /* GotoAdr */ ! 520: ! 521: ! 522: /* I N I T S A */ ! 523: ! 524: export void InitSa() ! 525: { ! 526: /* the 'Q' option shuts up the printout of the signal settings */ ! 527: SaMaintain(SIGALRM, "srQ"); /* we don't stop, report or eat */ ! 528: SaMaintain(SIGKILL, "srQ"); ! 529: SaMaintain(SIGINT, "eQ"); /* we stop, report and eat */ ! 530: SaMaintain(SIGTRAP, "eQ"); /* we stop, report and eat */ ! 531: #ifdef BSD41 ! 532: SaMaintain(SIGCONT, "srQ"); ! 533: SaMaintain(SIGCHLD, "srQ"); ! 534: #endif ! 535: } /* InitSa */ ! 536: ! 537: ! 538: /* S A M A I N T A I N */ ! 539: ! 540: export void SaMaintain(sig, sbOptions) ! 541: int sig; ! 542: char *sbOptions; ! 543: { ! 544: pSAR sa; ! 545: ! 546: sa = vmpSigSa + sig; ! 547: /* we toggle options based on the flags: ! 548: * r = report, s = stop, e = eat signal ! 549: */ ! 550: if (strchr(sbOptions, 'r')) ! 551: sa->fNoReport = ~sa->fNoReport; ! 552: if (strchr(sbOptions, 's')) ! 553: sa->fNoStop = ~sa->fNoStop; ! 554: if (strchr(sbOptions, 'e')) ! 555: sa->fEatSig = ~sa->fEatSig; ! 556: ! 557: if (strchr(sbOptions, 'Q') == sbNil) { ! 558: printf(" Stop Eat Report Name\n"); ! 559: printf("%2d %c %c %c ", sig, ! 560: (sa->fNoStop) ? 'F':'T', ! 561: (sa->fEatSig) ? 'T':'F', ! 562: (sa->fNoReport) ? 'F':'T'); ! 563: PrintSig(sig); ! 564: printf("\n"); ! 565: } /* if */ ! 566: } /* SaMaintain */ ! 567: ! 568: ! 569: /* L I S T S A */ ! 570: ! 571: export void ListSa() ! 572: { ! 573: int sig; ! 574: pSAR sa; ! 575: ! 576: printf(" Stop Eat Report Name\n"); ! 577: for (sig=1; sig < NSIG; sig++) { ! 578: sa = vmpSigSa + sig; ! 579: printf("%2d %c %c %c ", sig, ! 580: (sa->fNoStop) ? 'F':'T', ! 581: (sa->fEatSig) ? 'T':'F', ! 582: (sa->fNoReport) ? 'F':'T'); ! 583: PrintSig(sig); ! 584: printf("\n"); ! 585: } /* for */ ! 586: } /* ListSa */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.