Annotation of cci/usr/src/bin/cdb/pt.c, revision 1.1.1.1

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 */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.