Annotation of MiNT/doc/ptracer.c, revision 1.1.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.