|
|
1.1 ! root 1: #ifndef lint ! 2: static char sccsid[] = "@(#)kstack.c 5.1 (Berkeley) 1/16/89"; ! 3: #endif ! 4: ! 5: /* ! 6: * adb - routines to probe the kernel stack when debugging post-mortem ! 7: * crash dumps. ! 8: */ ! 9: ! 10: #include "defs.h" ! 11: #include <ctype.h> ! 12: #include <machine/pte.h> ! 13: #include <machine/frame.h> ! 14: #include <machine/rpb.h> ! 15: ! 16: struct pte *sbr; ! 17: int slr; ! 18: struct pcb pcb; ! 19: ! 20: static caddr_t rpb, erpb; ! 21: static caddr_t intstack, eintstack; ! 22: static caddr_t ustack, eustack; ! 23: ! 24: char *malloc(); ! 25: ! 26: /* ! 27: * Convert a kernel virtual address to an (off_t) physical offset. ! 28: */ ! 29: #define kvtooff(a) ((off_t)(a) & ~KERNBASE) ! 30: ! 31: /* ! 32: * Check if an address is in one of the kernel's stacks: ! 33: * interrupt stack, rpb stack (during restart sequence), ! 34: * or u. stack. ! 35: */ ! 36: #define within(a, b, e) \ ! 37: ((addr_t)(a) >= (addr_t)(b) && (addr_t)(a) < (addr_t)(e)) ! 38: #define kstackaddr(a) \ ! 39: (within(a, intstack, eintstack) || \ ! 40: within(a, rpb + sizeof(struct rpb), erpb) || \ ! 41: within(a, ustack, eustack)) ! 42: ! 43: /* ! 44: * Determine whether we are looking at a kernel core dump, and if so, ! 45: * set sbr and slr and the current pcb. ! 46: */ ! 47: getkcore() { ! 48: struct nlist *sm, *ss, *mp; ! 49: ! 50: if ((sm = lookup("_Sysmap")) == NULL || ! 51: (ss = lookup("_Syssize")) == NULL || ! 52: (mp = lookup("_masterpaddr")) == NULL) ! 53: return (0); /* a.out is not a vmunix */ ! 54: datmap.m1.b = 0; ! 55: datmap.m1.e = -1L; ! 56: /* must set sbr, slr before setpcb() */ ! 57: sbr = (struct pte *)sm->n_value; ! 58: slr = ss->n_value; ! 59: adbprintf("sbr %X slr %X\n", sbr, slr); ! 60: setpcb((addr_t)mp->n_value); ! 61: getpcb(); ! 62: findstackframe(); ! 63: return (1); ! 64: } ! 65: ! 66: /* ! 67: * A version of lookup that never returns failure, and which returns ! 68: * the n_value field of the symbol found. ! 69: */ ! 70: static caddr_t ! 71: xlookup(sym) ! 72: char *sym; ! 73: { ! 74: struct nlist *sp; ! 75: ! 76: if ((sp = lookup(sym)) == NULL) { ! 77: adbprintf("symbol %s not found ... bad kernel core?\n", sym); ! 78: exit(1); ! 79: } ! 80: return ((caddr_t)sp->n_value); ! 81: } ! 82: ! 83: /* ! 84: * Find the current stack frame when debugging the kernel. ! 85: * If we're looking at a crash dump and this was not a ``clean'' ! 86: * crash, then we must search the interrupt stack carefully ! 87: * looking for a valid frame. ! 88: */ ! 89: findstackframe() ! 90: { ! 91: register char *cp; ! 92: register int n; ! 93: caddr_t addr; ! 94: struct frame fr; ! 95: char buf[256]; ! 96: ! 97: if (readcore(kvtooff(xlookup("_panicstr")), (caddr_t)&addr, ! 98: sizeof(addr)) != sizeof(addr) || addr == 0) ! 99: return; ! 100: n = readcore(kvtooff(addr), buf, sizeof(buf)); ! 101: for (cp = buf; --n > 0 && *cp != 0; cp++) ! 102: if (!isascii(*cp) || (!isprint(*cp) && !isspace(*cp))) ! 103: *cp = '?'; ! 104: *cp = '\0'; ! 105: adbprintf("panic: %s\n", buf); ! 106: ! 107: /* ! 108: * After a panic, look at the top of the rpb stack to find a stack ! 109: * frame. If this was a clean crash, i.e. one which left the ! 110: * interrupt and kernel stacks in a reasonable state, then we should ! 111: * find a pointer to the proper stack frame here (at location ! 112: * intstack-8). If we don't find a reasonable frame here, then we ! 113: * must search down through the interrupt stack. ! 114: */ ! 115: intstack = xlookup("_intstack"); ! 116: eintstack = xlookup("_Xdoadump"); /* XXX */ ! 117: rpb = xlookup("_rsstk"); /* XXX */ ! 118: erpb = rpb + NBPG - 2 * sizeof(long); ! 119: ustack = xlookup("_u"); ! 120: eustack = ustack + ctob(UPAGES); ! 121: ustack += (int)((struct user *)0)->u_stack; ! 122: (void) readcore(kvtooff(intstack - 8), (caddr_t)&addr, sizeof(addr)); ! 123: if (!getframe(addr, &fr) && !checkintstack(&addr, &fr)) { ! 124: /* search kernel stack? */ ! 125: prints("can't locate stack frame\n"); ! 126: return; ! 127: } ! 128: /* probably shouldn't clobber pcb, but for now this is easy */ ! 129: pcb.pcb_fp = (int)addr; ! 130: pcb.pcb_pc = fr.fr_savpc; ! 131: } ! 132: ! 133: /* ! 134: * Search interrupt stack for a valid frame. Return 1 if found, ! 135: * also setting *addr to the kernel address of the frame, and *frame ! 136: * to the frame at that address. ! 137: */ ! 138: checkintstack(addr, frame) ! 139: caddr_t *addr; ! 140: struct frame *frame; ! 141: { ! 142: register int ssize; ! 143: register char *stack; ! 144: ! 145: ssize = eintstack - intstack; ! 146: if ((stack = malloc((u_int)ssize)) == NULL) ! 147: return (0); ! 148: if (readcore(kvtooff(intstack), stack, ssize) != ssize) { ! 149: free(stack); ! 150: return (0); ! 151: } ! 152: for (ssize -= sizeof(*frame); ssize >= 0; ssize -= 4) { ! 153: if (goodframe((struct frame *)&stack[ssize])) { ! 154: *addr = &intstack[ssize] + FRAMEOFF; ! 155: *frame = *(struct frame *)&stack[ssize]; ! 156: free(stack); ! 157: return (1); ! 158: } ! 159: } ! 160: free(stack); ! 161: return (0); ! 162: } ! 163: ! 164: /* ! 165: * Get a stack frame and verify that it looks like ! 166: * something which might be on a kernel stack. Return 1 if OK. ! 167: */ ! 168: getframe(addr, fp) ! 169: caddr_t addr; ! 170: struct frame *fp; ! 171: { ! 172: off_t off; ! 173: char *err = NULL; ! 174: ! 175: if (!kstackaddr(addr)) ! 176: return (0); ! 177: off = vtophys((addr_t)(addr - FRAMEOFF), &err); ! 178: if (err || readcore(off, (caddr_t)fp, sizeof(*fp)) != sizeof(*fp)) ! 179: return (0); ! 180: return (goodframe(fp)); ! 181: } ! 182: ! 183: /* ! 184: * Check a call frame to see if it's ok as a kernel stack frame. ! 185: * It should have its parent frame in the kernel stack, and should ! 186: * return to kernel code. ! 187: */ ! 188: goodframe(fr) ! 189: register struct frame *fr; ! 190: { ! 191: ! 192: return (kstackaddr(fr->fr_savfp) && ! 193: within(fr->fr_savpc, txtmap.m1.b, txtmap.m1.e)); ! 194: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.