|
|
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.