|
|
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:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.