|
|
1.1 ! root 1: /* ! 2: * File: dcore.c ! 3: * ! 4: * Purpose: Display contents of core file intelligibly. ! 5: * ! 6: * $Log: dcore.c,v $ ! 7: * Revision 1.1 93/04/16 07:01:38 bin ! 8: * Initial revision ! 9: * ! 10: */ ! 11: ! 12: /* ! 13: * ---------------------------------------------------------------------- ! 14: * Includes. ! 15: */ ! 16: #include <stdio.h> ! 17: #include <sys/core.h> ! 18: #include <sys/reg.h> ! 19: #include <sys/uproc.h> ! 20: ! 21: /* ! 22: * ---------------------------------------------------------------------- ! 23: * Definitions. ! 24: * Constants. ! 25: * Macros with argument lists. ! 26: * Typedefs. ! 27: * Enums. ! 28: */ ! 29: #define DEFAULT_CORE_NAME "core" ! 30: #define DSIZE 16 ! 31: ! 32: struct seg_info { ! 33: int si_base; ! 34: int si_size; ! 35: long si_offset; ! 36: }; ! 37: ! 38: /* ! 39: * ---------------------------------------------------------------------- ! 40: * Functions. ! 41: * Import Functions. ! 42: * Export Functions. ! 43: * Local Functions. ! 44: */ ! 45: ! 46: /* ! 47: * ---------------------------------------------------------------------- ! 48: * Global Data. ! 49: * Import Variables. ! 50: * Export Variables. ! 51: * Local Variables. ! 52: */ ! 53: static char * cmd; ! 54: static int tflag; /* "-t" option says text segment was dumped */ ! 55: static char * coreName = DEFAULT_CORE_NAME; ! 56: static FILE * fp; ! 57: static struct ch_info chInfo; ! 58: static char *segName[NUSEG] = { ! 59: "USER", "TEXT", "DATA", "STACK" ! 60: }; ! 61: static struct seg_info segInfo[NUSEG]; ! 62: ! 63: /* ! 64: * ---------------------------------------------------------------------- ! 65: * Code. ! 66: */ ! 67: ! 68: void ! 69: usage() ! 70: { ! 71: fprintf(stderr, "Usage: %s [-t] [corefile]\n", cmd); ! 72: exit(1); ! 73: } ! 74: ! 75: /* ! 76: * Given text name and vital stats for a segment, do a hex dump. ! 77: */ ! 78: void ! 79: dumpseg(name, infop) ! 80: char *name; ! 81: struct seg_info *infop; ! 82: { ! 83: /* use the fact that segment size is a multiple of NBPC */ ! 84: unsigned char coredata[DSIZE]; ! 85: unsigned char savedata[DSIZE]; ! 86: int segOffset; ! 87: int i; ! 88: /* ! 89: * sameState: ! 90: * -1 just starting; don't look for matching display lines ! 91: * 0 current line does not match previous line ! 92: * 1 current line matches previous line ! 93: * 2 current line matches previous 2 or more lines ! 94: */ ! 95: int sameState = -1; ! 96: int doPrint, match; ! 97: ! 98: /* make sure we can seek to start of segment */ ! 99: if (fseek(fp, infop->si_offset, 0) < 0) { ! 100: fprintf(stderr, "Can't seek to %s segment!\n", name); ! 101: exit(1); ! 102: } ! 103: ! 104: printf("\nContents of %s segment:\n", name); ! 105: for (segOffset = 0; segOffset < infop->si_size; segOffset += DSIZE) { ! 106: int readLen = DSIZE; ! 107: int remains = infop->si_size - segOffset; ! 108: ! 109: if (readLen > remains) ! 110: readLen = remains; ! 111: ! 112: if (fread(coredata, readLen, 1, fp) !=1) { ! 113: fprintf(stderr, "Can't read core data.\n"); ! 114: exit(1); ! 115: } ! 116: ! 117: /* always display last line of segment */ ! 118: if (remains <= DSIZE) ! 119: match = 1; ! 120: else ! 121: match = memcmp(coredata, savedata, DSIZE); ! 122: ! 123: switch(sameState) { ! 124: case -1: ! 125: sameState = 0; ! 126: doPrint = 1; ! 127: break; ! 128: case 0: ! 129: if (match) { ! 130: doPrint = 1; ! 131: } else { ! 132: sameState = 1; ! 133: doPrint = 0; ! 134: } ! 135: break; ! 136: case 1: ! 137: if (match) { ! 138: doPrint = 1; ! 139: sameState = 0; ! 140: } else { ! 141: sameState = 2; ! 142: doPrint = 0; ! 143: printf(" *\n"); ! 144: } ! 145: break; ! 146: case 2: ! 147: if (match) { ! 148: doPrint = 1; ! 149: sameState = 0; ! 150: } else { ! 151: doPrint = 0; ! 152: } ! 153: break; ! 154: } ! 155: if (doPrint) { ! 156: printf("%06X", segOffset); ! 157: for (i = 0; i < readLen; i++) ! 158: printf(" %02X", coredata[i]); ! 159: printf("\n"); ! 160: } ! 161: memcpy(savedata, coredata, DSIZE); ! 162: } ! 163: } ! 164: ! 165: /* ! 166: * Once the file has been opened and magic number checked, this function ! 167: * does the work. ! 168: * ! 169: * Globals used: fp, chInfo. ! 170: */ ! 171: void ! 172: dcore() ! 173: { ! 174: long offset; ! 175: static struct uproc uProc; ! 176: static int regs[SS+1]; ! 177: int i; ! 178: int base, size; ! 179: ! 180: /* display uproc version number */ ! 181: offset = chInfo.ch_info_len + chInfo.ch_uproc_offset; ! 182: if (fseek(fp, offset, 0) < 0) { ! 183: fprintf(stderr, "Can't seek to uproc.\n"); ! 184: exit(1); ! 185: } ! 186: if (fread(&uProc, sizeof(uProc), 1, fp) !=1) { ! 187: fprintf(stderr, "Can't read uproc.\n"); ! 188: exit(1); ! 189: } ! 190: printf("uproc version = 0x%04x\n", uProc.u_version); ! 191: ! 192: /* display register set */ ! 193: offset = chInfo.ch_info_len + ((int)(uProc.u_regl) & (NBPC-1)); ! 194: if (fseek(fp, offset, 0) < 0) { ! 195: fprintf(stderr, "Can't seek to register set.\n"); ! 196: exit(1); ! 197: } ! 198: if (fread(regs, sizeof(regs), 1, fp) !=1) { ! 199: fprintf(stderr, "Can't read register set.\n"); ! 200: exit(1); ! 201: } ! 202: ! 203: printf("\neax=%08X\tebx=%08X\tecx=%08X\tedx=%08X\n", ! 204: regs[EAX], regs[EBX], regs[ECX], regs[EDX]); ! 205: printf("esi=%08X\tedi=%08X\tebp=%08X\tesp=%08X\n", ! 206: regs[ESI], regs[EDI], regs[EBP], regs[ESP]); ! 207: printf("eip=%08X\tuesp=%08X\tefl=%08X\n", ! 208: regs[EIP], regs[UESP], regs[EFL]); ! 209: printf("\ncs=%04X\tds=%04X\tes=%04X\tss=%04X\tfs=%04X\tgs=%04X\n", ! 210: regs[CS]&0xffff, regs[DS]&0xffff, regs[ES]&0xffff, ! 211: regs[SS]&0xffff, regs[FS]&0xffff, regs[GS]&0xffff); ! 212: printf("\nerr #%d \tcmd=%s\n", regs[ERR], uProc.u_comm); ! 213: ! 214: /* display segment sizes */ ! 215: printf("\nSegment\tBase\t\tSize\n"); ! 216: offset = chInfo.ch_info_len; ! 217: for (i = 0; i < NUSEG; i++) { ! 218: base = (int)(uProc.u_segl[i].sr_base); ! 219: size = uProc.u_segl[i].sr_size; ! 220: if (i == SISTACK) ! 221: base -= size; ! 222: printf("%s\t%08x\t%08x\n", segName[i], base, size); ! 223: segInfo[i].si_offset = offset; ! 224: segInfo[i].si_base = base; ! 225: segInfo[i].si_size = size; ! 226: ! 227: /* text is in core file only if "-t" specified */ ! 228: if (tflag || i != SISTEXT) ! 229: offset += size; ! 230: } ! 231: ! 232: /* dump segments */ ! 233: for (i = 0; i < NUSEG; i++) { ! 234: if (!tflag && i == SISTEXT) ! 235: continue; ! 236: dumpseg(segName[i], segInfo + i); ! 237: } ! 238: } ! 239: ! 240: main(argc, argv) ! 241: int argc; ! 242: char *argv[]; ! 243: { ! 244: int argn; ! 245: ! 246: /* command line housekeeping */ ! 247: cmd = argv[0]; ! 248: for (argn = 1; argn < argc; argn++) { ! 249: if (argv[argn][0] == '-') { ! 250: switch(argv[argn][1]) { ! 251: case 't': ! 252: tflag = 1; ! 253: break; ! 254: default: ! 255: usage(); ! 256: } ! 257: } else { ! 258: coreName = argv[argn]; ! 259: /* this should be the last argument */ ! 260: if (argn < argc - 1) ! 261: usage(); ! 262: } ! 263: } ! 264: ! 265: /* try to open the core file for reading */ ! 266: if ((fp = fopen(coreName, "r")) == NULL) { ! 267: fprintf(stderr, "Can't open %s for reading.\n", coreName); ! 268: exit(1); ! 269: } ! 270: ! 271: /* simple test for core file format */ ! 272: if (fread(&chInfo, sizeof(chInfo), 1, fp) !=1) { ! 273: fprintf(stderr, "Can't read core header.\n"); ! 274: exit(1); ! 275: } ! 276: ! 277: if (chInfo.ch_magic != CORE_MAGIC) { ! 278: fprintf(stderr, "Not a core file.\n"); ! 279: exit(1); ! 280: } ! 281: printf("Core file: %s ", coreName); ! 282: ! 283: /* call a function to do the work */ ! 284: dcore(); ! 285: ! 286: /* cleanup */ ! 287: fclose(fp); ! 288: exit(0); ! 289: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.