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