📄 postmort.c
字号:
buff[9] = '$'; (void) binary((int) uc, buff + 10); /* Print all the information */ printf("Stack Frame:\tPC = %04.4x\t\t PSW = %s\n", sp->pc, buff); printf("\t\t\t\t\tStatus = ____ ODIT SZ_A _P_C\n"); printf(" ax bx cx dx di si\n"); printf(" %04.4x\t%04.4x\t%04.4x\t%04.4x\t%04.4x\t%04.4x\n", sp->retreg, sp->bx, sp->cx, sp->dx, sp->di, sp->si); printf(" sp bp ss\n"); printf(" %04.4x\t%04.4x\t%04.4x\n", sp->sp, sp->fp, sp->ss); printf(" cs ds es\n"); printf(" %04.4x\t%04.4x\t%04.4x\n", sp->cs, sp->ds, sp->es); /* Store for future reference */ stackptr = sp->sp; baseptr = sp->fp; if (dbglvl > 0) printf("\nStack pointer 0x%x, Base pointer 0x%x\n", stackptr, baseptr);}/* M a i n * * Main program */main(argc, argv)int argc;char *argv[];{ int j, fdc, fds; char *cp, corefile[132], symbfile[132]; struct proc proc_entry; struct mem_map mp_segs[NR_SEGS]; /* Initial set up */ if ((cp = strrchr(argv[0], '/')) == (char *) NULL) cp = argv[0]; else cp++; strncpy(progname, cp, 19); strncpy(corefile, CORE, 131); strncpy(symbfile, AOUT, 131); /* Parse arguments */ opterr = 0; while ((j = getopt(argc, argv, "c:dps:tx:")) != EOF) { switch (j & 0177) { case 'c': opt_c = TRUE; strncpy(corefile, optarg, 131); break; case 'd': opt_d = TRUE; break; case 'p': opt_p = TRUE; break; case 's': opt_s = TRUE; strncpy(symbfile, optarg, 131); break; case 't': opt_t = TRUE; break; case 'x': dbglvl = atoi(optarg); opt_x = TRUE; break; case '?': default: usage(); exit(1); break; } } /* We must have a core file */ if ((fdc = open(corefile, O_RDONLY)) == -1) { fprintf(stderr, "Cannot open %s\n", corefile); exit(1); } /* We'd like an a.out file or a symbol table */ if ((fds = open(symbfile, O_RDONLY)) == -1) { if (opt_s) j = FAILED; else { strncpy(symbfile, AOUT, 131); if ((fds = open(symbfile, O_RDONLY)) == -1) j = FAILED; else j = read_symbol(fds); } } else j = read_symbol(fds); /* Only fatal if we insisted */ if (opt_s && j == FAILED) { fprintf(stderr, "Cannot find symbols in %s\n", symbfile); exit(1); } /* Read the process table */ if (dbglvl > 0) { printf("\n"); printf("Size of mproc entry %d\n", NR_SEGS * sizeof(struct mem_map)); printf("Size of process table %d\n", sizeof(proc_entry)); } if (read(fdc, (char *) mp_segs, sizeof(mp_segs)) != sizeof(mp_segs) || read(fdc, (char *) &proc_entry, sizeof(struct proc)) != sizeof(struct proc)) { fprintf(stderr, "Cannot open %s\n", corefile); exit(1); } /* Do the work */#if 0 dump_maps(mp_segs); /* duplicated in the kernel */ printf("\n");#endif dump_maps(proc_entry.p_map); printf("\n"); dump_registers(&proc_entry); if (opt_t) { printf("\n"); stack_trace(fdc); } if (opt_p) { printf("\n"); dump_proc_table(&proc_entry); } if (opt_d) { printf("\n"); dump_sym_tab(symtab); dump_all_segs(fdc); } /* Wrap up */ (void) close(fdc); if (fds != -1) (void) close(fds); exit(0); /* NOTREACHED */}/* P a r s e _ l i n e * * Parse a line of the symbol table */int parse_line(ps)char *ps;{ char c, s[80]; int j, k; unsigned int u; /* We must have space in the table */ if (maxsym == MAXSYM) return(FAILED); /* Lines must be a minimum length to contain information */ if (strlen(ps) < 8) return(FAILED); /* Lines must have a definite structure */ if (ps[1] != ' ' || ps[6] != ' ') return(FAILED); for (j = 2; j < 6; j++) if (!isxdigit(ps[j])) return(FAILED); if (sscanf(ps, "%c %x %s", &c, &u, s) != 3) return (FAILED); if (dbglvl > 0) printf("Address 0x%04.4x, label %s\n", u, s); /* Load the symbol table in sorted order */ for (j = 0; j < maxsym; j++) { if (u < symtab[j].addr) { for (k = maxsym; k > j; k--) symtab[k] = symtab[k - 1]; break; } } symtab[j].addr = u; strncpy(symtab[j].label, s, SYMLEN); maxsym++; return(OK);}/* R e a d _ s y m b o l * * Read the symbol table */int read_symbol(fd)int fd;{ char sym[80], buff[BUFSIZ]; int j, k, m; long int offset; struct exec *ep; struct nlist *np; /* We collect only text symbols, since that's all that's needed here */ /* Initialise the buffer */ if ((j = read(fd, buff, BUFSIZ)) == 0 || j == -1) return(FAILED); k = maxsym = 0; /* Find out what we've got */ ep = (struct exec *) buff; np = (struct nlist *) buff; if (BADMAG(*ep)) { /* Must be a separate symbol table */ while (TRUE) { if (buff[k] == 'T') { for (m = 0; m < 78; m++) { sym[m] = buff[k]; if (++k == j) { if ((j = read(fd, buff, BUFSIZ)) == 0 || j == -1) break; k = 0; } if (buff[k] == '\n') break; } sym[m + 1] = '\0'; (void) parse_line(sym); } if (++k == j) { if ((j = read(fd, buff, BUFSIZ)) == 0 || j == -1) break; k = 0; } } } else if (ep->a_syms != 0L) { /* There's symbols in them thar hills */ offset = 8 * sizeof(long) + ep->a_text + ep->a_data; if (lseek(fd, offset, 0) == -1L) return(FAILED); /* Symbols are in an unsorted list */ while (read(fd, buff, sizeof(struct nlist)) == sizeof(struct nlist)) { if (np->n_sclass == (N_TEXT + C_EXT)) { /* external text symbols */ for (j = 0; j < maxsym; j++) { if (np->n_value < symtab[j].addr) { for (k = maxsym; k > j; k--) symtab[k] = symtab[k - 1]; break; } } symtab[j].addr = np->n_value; strncpy(symtab[j].label, np->n_name, SYMLEN); if (maxsym++ == MAXSYM) break; } } } else if (opt_s) return(FAILED); if (dbglvl > 0) { for (m = 0; m < maxsym; m++) printf("Addr 0x%04.4x, label %s\n", symtab[m].addr, symtab[m].label); printf("Maxsym %d\n", maxsym); } return(OK);}/* S t a c k _ t r a c e * * Trace back down the stack frames. * * WARNING: very, very, non-portable code */void stack_trace(fd)int fd;{ int j; unsigned int framepointer, lastpointer, returnvalue, end; long int offset, bp; /* Bp actually gives the offset from the base of the data segment */ bp = (long) (NR_SEGS * sizeof(struct mem_map)) + sizeof(struct proc) + lengths[0] + lengths[1] - bases[2]; if ((offset = lseek(fd, bp + (long int) baseptr, 0)) == -1L) return; end = (bases[2] + lengths[2] - 1) & 0xffff; if (dbglvl > 0) printf("Baseptr %x, End %x, Bp %ld, Offset %ld\n", baseptr, end, bp, offset); /* Print the header, then try to backtrace */ printf("Stack back trace:\n\n"); printf("Frame address. Contents. Return address."); if (maxsym != 0) printf(" Previous label."); printf("\n"); lastpointer = baseptr; while (TRUE) { /* Read the frame pointer and return address values */ if (read(fd, (char *) &framepointer, sizeof(int)) == -1 || read(fd, (char *) &returnvalue, sizeof(int)) == -1) break; /* Look up the return address - ignored if maxsym == 0 */ for (j = 0; j < maxsym; j++) { if (symtab[j].addr >= returnvalue) break; } if (j > 0) j--; printf(" 0x%04.4x 0x%04.4x 0x%04.4x %s\n", lastpointer, framepointer, returnvalue, (maxsym == 0) ? "" : symtab[j].label); /* If the result is clearly invalid, quit */ if (framepointer == 0 || framepointer >= end || framepointer <= lastpointer) break; /* Otherwise try to move to the next frame base */ lastpointer = framepointer; if ((offset = lseek(fd, bp + (long int) framepointer, 0)) == -1L || offset == 0L) break; }}/* U s a g e * * Usage message */void usage(){ fprintf(stderr, "Usage: %s [-dpt] [-c corefile] [-s symbfile]\n", progname);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -