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