Annotation of MiNT/doc/ptracer.c, revision 1.1

1.1     ! root        1: /*
        !             2: 
        !             3:  * sample program for demonstrating the debugging calls
        !             4: 
        !             5:  * Written by Alex Kiernan
        !             6: 
        !             7:  */
        !             8: 
        !             9: 
        !            10: 
        !            11: #include <mintbind.h>
        !            12: 
        !            13: #include <stddef.h>
        !            14: 
        !            15: 
        !            16: 
        !            17: typedef struct _context {
        !            18: 
        !            19:        long    regs[15];       /* registers d0-d7, a0-a6 */
        !            20: 
        !            21:        long    usp;            /* user stack pointer (a7) */
        !            22: 
        !            23:        short   sr;             /* status register */
        !            24: 
        !            25:        long    pc;             /* program counter */
        !            26: 
        !            27:        long    ssp;            /* supervisor stack pointer */
        !            28: 
        !            29:        long    term_vec;       /* GEMDOS terminate vector (0x102) */
        !            30: 
        !            31: /*
        !            32: 
        !            33:  * AGK: if running on a TT and the user is playing with the FPU then we
        !            34: 
        !            35:  * must save and restore the context. We should also consider this for
        !            36: 
        !            37:  * I/O based co-processors, although this may be difficult due to
        !            38: 
        !            39:  * possibility of a context switch in the middle of an I/O handshaking
        !            40: 
        !            41:  * exchange.
        !            42: 
        !            43:  */
        !            44: 
        !            45:        unsigned char   fstate[216];    /* FPU internal state */
        !            46: 
        !            47:        long    fregs[3*8];     /* registers fp0-fp7 */
        !            48: 
        !            49:        long    fctrl[3];       /* FPCR/FPSR/FPIAR */
        !            50: 
        !            51: /*
        !            52: 
        !            53:  * AGK: for long (time-wise) co-processor instructions (FMUL etc.), the
        !            54: 
        !            55:  * FPU returns NULL, come-again with interrupts allowed primitives. It
        !            56: 
        !            57:  * is highly likely that a context switch will occur in one of these if
        !            58: 
        !            59:  * running a mathematically intensive application, hence we must handle
        !            60: 
        !            61:  * the mid-instruction interrupt stack. We do this by saving the extra
        !            62: 
        !            63:  * 3 long words and the stack format word here.
        !            64: 
        !            65:  */
        !            66: 
        !            67:        unsigned short  sfmt;   /* stack frame format identifier */
        !            68: 
        !            69:        short   internal[42];   /* internal state -- see framesizes[] for size */
        !            70: 
        !            71:        char    ptrace;         /* trace exception is pending */
        !            72: 
        !            73: } CONTEXT;
        !            74: 
        !            75: 
        !            76: 
        !            77: #define PPROCADDR      (('P'<< 8) | 1)
        !            78: 
        !            79: #define PBASEADDR      (('P'<< 8) | 2)
        !            80: 
        !            81: #define PCTXTSIZE      (('P'<< 8) | 3)
        !            82: 
        !            83: #define PSETFLAGS      (('P'<< 8) | 4)
        !            84: 
        !            85: #define PGETFLAGS      (('P'<< 8) | 5)
        !            86: 
        !            87: #define PTRACESFLAGS   (('P'<< 8) | 6)
        !            88: 
        !            89: #define PTRACEGFLAGS   (('P'<< 8) | 7)
        !            90: 
        !            91: #      define  P_ENABLE        (1 << 0)        /* enable tracing */
        !            92: 
        !            93: #ifdef NOTYETDEFINED
        !            94: 
        !            95: #      define  P_DOS           (1 << 1)        /* trace DOS calls - unimplemented */
        !            96: 
        !            97: #      define  P_BIOS          (1 << 2)        /* trace BIOS calls - unimplemented */
        !            98: 
        !            99: #      define  P_XBIOS         (1 << 3)        /* trace XBIOS calls - unimplemented */
        !           100: 
        !           101: #endif
        !           102: 
        !           103: 
        !           104: 
        !           105: #define PTRACEGO       (('P'<< 8) | 8) /* these 4 must be together */
        !           106: 
        !           107: #define PTRACEFLOW     (('P'<< 8) | 9)
        !           108: 
        !           109: #define PTRACESTEP     (('P'<< 8) | 10)
        !           110: 
        !           111: #define PTRACE11       (('P'<< 8) | 11)
        !           112: 
        !           113: 
        !           114: 
        !           115: /* lseek() origins */
        !           116: 
        !           117: #define        SEEK_SET        0               /* from beginning of file */
        !           118: 
        !           119: #define        SEEK_CUR        1               /* from current location */
        !           120: 
        !           121: #define        SEEK_END        2               /* from end of file */
        !           122: 
        !           123: 
        !           124: 
        !           125: #define WNOHANG         1
        !           126: 
        !           127: #define WUNTRACED      2
        !           128: 
        !           129: 
        !           130: 
        !           131: /* these definitions are incompatible with <sys/wait.h> */
        !           132: 
        !           133: #define WIFEXITED(x)   ((int)((x) & 0xFF00) == 0)
        !           134: 
        !           135: #define WEXITSTATUS(x) ((int)((x) & 0xFF))
        !           136: 
        !           137: 
        !           138: 
        !           139: #define WIFSIGNALED(x) (((int)((x) & 0xFF00) > 0) && ((int)(((x) & 0xFF) == 0)))
        !           140: 
        !           141: #define WTERMSIG(x)    ((int)(((x) & 0xFF00) >> 8))
        !           142: 
        !           143: 
        !           144: 
        !           145: #define WIFSTOPPED(x)  (((int)((x) & 0xFF) == 0x7F) && ((int)(((x) >> 8) & 0xFF) != 0))
        !           146: 
        !           147: #define WSTOPSIG(x)    ((int)(((x) >> 8) & 0xFF))
        !           148: 
        !           149: 
        !           150: 
        !           151: #define SIGTRAP                5               /* trace trap */
        !           152: 
        !           153: 
        !           154: 
        !           155: void
        !           156: 
        !           157: dumpCTXT(ctxt)
        !           158: 
        !           159:        CONTEXT *ctxt;
        !           160: 
        !           161: {
        !           162: 
        !           163:        int i, j;
        !           164: 
        !           165: 
        !           166: 
        !           167:        for (i = 0; i < 16; i += 4) {
        !           168: 
        !           169:                for (j = 0; j < 4; j++) {
        !           170: 
        !           171:                        /* oh dear... we output too many commas - c'est la vie */
        !           172: 
        !           173:                        printf("%c%d=$%08lx, ", i < 8 ? 'D' : 'A',
        !           174: 
        !           175:                          i + j - (i >= 8 ? 8 : 0),
        !           176: 
        !           177:                          ctxt[0].regs[i + j]);
        !           178: 
        !           179:                }
        !           180: 
        !           181:                putchar('\n');
        !           182: 
        !           183:        }
        !           184: 
        !           185:        printf("SR=$%04x\n", ctxt[0].sr);
        !           186: 
        !           187:        printf("PC=$%08lx\n", ctxt[0].pc);
        !           188: 
        !           189:        printf("SSP=$%08lx\n", ctxt[0].ssp);
        !           190: 
        !           191:        printf("term_vec=$%08lx\n", ctxt[0].term_vec);
        !           192: 
        !           193:        printf("fstate[0]=%u\n", ctxt[0].fstate[0]);
        !           194: 
        !           195:        for (i = 0; i < 8; i++) {
        !           196: 
        !           197:                printf("FP%d=$%08lx%08lx%08lx\n",
        !           198: 
        !           199:                  i,
        !           200: 
        !           201:                  ctxt[0].fregs[i * 3 + 0],
        !           202: 
        !           203:                  ctxt[0].fregs[i * 3 + 1],
        !           204: 
        !           205:                  ctxt[0].fregs[i * 3 + 2]);
        !           206: 
        !           207:        }
        !           208: 
        !           209:        printf("frame format=%u\n", ctxt[0].sfmt >> 12);
        !           210: 
        !           211:        printf("vector offset=$%x\n", ctxt[0].sfmt & 0xfff);
        !           212: 
        !           213:        /* could print internal state here internal[0..41] */
        !           214: 
        !           215: }
        !           216: 
        !           217: 
        !           218: 
        !           219: int
        !           220: 
        !           221: main(argc,argv)
        !           222: 
        !           223:        int argc;
        !           224: 
        !           225:        char *argv[];
        !           226: 
        !           227: {
        !           228: 
        !           229:        int pid;
        !           230: 
        !           231:        unsigned long status;
        !           232: 
        !           233:        int fd;
        !           234: 
        !           235:        char fpid[13];
        !           236: 
        !           237:        CONTEXT ctxt;
        !           238: 
        !           239:        long pctxt;
        !           240: 
        !           241:        long sizeof_ctxt;
        !           242: 
        !           243:        unsigned short sig;
        !           244: 
        !           245:        
        !           246: 
        !           247:        if (isdigit(*argv[1])) {
        !           248: 
        !           249:                pid = atoi(argv[1]);
        !           250: 
        !           251:                sprintf(fpid, "U:\\PROC\\.%03d", pid);
        !           252: 
        !           253:                fd = Fopen(fpid, 0);
        !           254: 
        !           255:                sig = 1;
        !           256: 
        !           257:                Fcntl(fd, (long)&sig, PTRACESFLAGS);    /* capture it */
        !           258: 
        !           259:                Pkill(pid, SIGTRAP);            /* and stop it */
        !           260: 
        !           261:        }
        !           262: 
        !           263:        else {
        !           264: 
        !           265:                pid = Pexec(0x8000 | 100, argv[1], "\0", NULL);
        !           266: 
        !           267:                /* check pid */
        !           268: 
        !           269:                printf("pid = %d\n", pid);
        !           270: 
        !           271:                sprintf(fpid, "U:\\PROC\\.%03d", pid);
        !           272: 
        !           273:                fd = Fopen(fpid, 0);
        !           274: 
        !           275:        }
        !           276: 
        !           277:        /* check fd */
        !           278: 
        !           279:        Fcntl(fd, (long)&pctxt, PPROCADDR);
        !           280: 
        !           281:        Fcntl(fd, (long)&sizeof_ctxt, PCTXTSIZE);
        !           282: 
        !           283:        pctxt -= 2 * sizeof_ctxt;
        !           284: 
        !           285: 
        !           286: 
        !           287:        do {
        !           288: 
        !           289:                status = Pwait3(WUNTRACED, NULL);
        !           290: 
        !           291:                if (WIFSTOPPED(status)) {
        !           292: 
        !           293:                        printf("pid = %d\, WSTOPSIG = %d\n", (int)(status >> 16), WSTOPSIG(status));
        !           294: 
        !           295:                        Fseek((long)pctxt, fd, SEEK_SET);
        !           296: 
        !           297:                        Fread(fd, sizeof(ctxt), &ctxt); /* note _not_ sizeof_ctxt */
        !           298: 
        !           299:                        dumpCTXT(&ctxt);
        !           300: 
        !           301:                        switch (Cconin() & 0xff) {
        !           302: 
        !           303:                                case 's':
        !           304: 
        !           305:                                case 'S':
        !           306: 
        !           307:                                        Fcntl(fd, (long)NULL, PTRACESTEP);      /* single step */
        !           308: 
        !           309:                                        break;
        !           310: 
        !           311:                                        
        !           312: 
        !           313:                                case 'g':
        !           314: 
        !           315:                                case 'G':
        !           316: 
        !           317:                                        Fcntl(fd, (long)NULL, PTRACEGO);        /* go */
        !           318: 
        !           319:                                        break;
        !           320: 
        !           321:                                        
        !           322: 
        !           323:                                case 'f':
        !           324: 
        !           325:                                case 'F':
        !           326: 
        !           327:                                        Fcntl(fd, (long)NULL, PTRACEFLOW);      /* go to flow change */
        !           328: 
        !           329:                                        break;
        !           330: 
        !           331:                                        
        !           332: 
        !           333:                                case 'x':
        !           334: 
        !           335:                                case 'X':
        !           336: 
        !           337:                                        sig = WSTOPSIG(status);
        !           338: 
        !           339:                                        Fcntl(fd, (long)&sig, PTRACEGO);        /* kill it */
        !           340: 
        !           341:                                        break;
        !           342: 
        !           343:                        }
        !           344: 
        !           345:                }
        !           346: 
        !           347:                putchar('\n');
        !           348: 
        !           349:        } while (!WIFEXITED(status) && !WIFSIGNALED(status));
        !           350: 
        !           351:        if (WIFEXITED(status))
        !           352: 
        !           353:                printf("pid = %d, WEXITSTATUS = %d\n", (int)(status >> 16), WEXITSTATUS(status));
        !           354: 
        !           355:        else
        !           356: 
        !           357:                printf("pid = %d, WTERMSIG = %d\n", (int)(status >> 16), WTERMSIG(status));
        !           358: 
        !           359:        Fclose(fd);     /* but the process is dead... (Jim!) */
        !           360: 
        !           361:        return 0;
        !           362: 
        !           363: }
        !           364: 

unix.superglobalmegacorp.com

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