subr_kdb.c revision 159726
1/*-
2 * Copyright (c) 2004 The FreeBSD Project
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27#include <sys/cdefs.h>
28__FBSDID("$FreeBSD: head/sys/kern/subr_kdb.c 159726 2006-06-18 12:27:59Z yar $");
29
30#include "opt_kdb.h"
31
32#include <sys/param.h>
33#include <sys/systm.h>
34#include <sys/kdb.h>
35#include <sys/kernel.h>
36#include <sys/malloc.h>
37#include <sys/pcpu.h>
38#include <sys/proc.h>
39#include <sys/smp.h>
40#include <sys/sysctl.h>
41
42#include <machine/kdb.h>
43#include <machine/pcb.h>
44
45#ifdef SMP
46#include <machine/smp.h>
47#endif
48
49int kdb_active = 0;
50void *kdb_jmpbufp = NULL;
51struct kdb_dbbe *kdb_dbbe = NULL;
52struct pcb kdb_pcb;
53struct pcb *kdb_thrctx = NULL;
54struct thread *kdb_thread = NULL;
55struct trapframe *kdb_frame = NULL;
56
57KDB_BACKEND(null, NULL, NULL, NULL);
58SET_DECLARE(kdb_dbbe_set, struct kdb_dbbe);
59
60static int kdb_sysctl_available(SYSCTL_HANDLER_ARGS);
61static int kdb_sysctl_current(SYSCTL_HANDLER_ARGS);
62static int kdb_sysctl_enter(SYSCTL_HANDLER_ARGS);
63static int kdb_sysctl_panic(SYSCTL_HANDLER_ARGS);
64static int kdb_sysctl_trap(SYSCTL_HANDLER_ARGS);
65static int kdb_sysctl_trap_code(SYSCTL_HANDLER_ARGS);
66
67SYSCTL_NODE(_debug, OID_AUTO, kdb, CTLFLAG_RW, NULL, "KDB nodes");
68
69SYSCTL_PROC(_debug_kdb, OID_AUTO, available, CTLTYPE_STRING | CTLFLAG_RD, 0, 0,
70    kdb_sysctl_available, "A", "list of available KDB backends");
71
72SYSCTL_PROC(_debug_kdb, OID_AUTO, current, CTLTYPE_STRING | CTLFLAG_RW, 0, 0,
73    kdb_sysctl_current, "A", "currently selected KDB backend");
74
75SYSCTL_PROC(_debug_kdb, OID_AUTO, enter, CTLTYPE_INT | CTLFLAG_RW, 0, 0,
76    kdb_sysctl_enter, "I", "set to enter the debugger");
77
78SYSCTL_PROC(_debug_kdb, OID_AUTO, panic, CTLTYPE_INT | CTLFLAG_RW, 0, 0,
79    kdb_sysctl_panic, "I", "set to panic the kernel");
80
81SYSCTL_PROC(_debug_kdb, OID_AUTO, trap, CTLTYPE_INT | CTLFLAG_RW, 0, 0,
82    kdb_sysctl_trap, "I", "set to cause a page fault via data access");
83
84SYSCTL_PROC(_debug_kdb, OID_AUTO, trap_code, CTLTYPE_INT | CTLFLAG_RW, 0, 0,
85    kdb_sysctl_trap_code, "I", "set to cause a page fault via code access");
86
87/*
88 * Flag indicating whether or not to IPI the other CPUs to stop them on
89 * entering the debugger.  Sometimes, this will result in a deadlock as
90 * stop_cpus() waits for the other cpus to stop, so we allow it to be
91 * disabled.
92 */
93#ifdef SMP
94static int kdb_stop_cpus = 1;
95SYSCTL_INT(_debug_kdb, OID_AUTO, stop_cpus, CTLTYPE_INT | CTLFLAG_RW,
96    &kdb_stop_cpus, 0, "stop other CPUs when entering the debugger");
97TUNABLE_INT("debug.kdb.stop_cpus", &kdb_stop_cpus);
98#endif
99
100static int
101kdb_sysctl_available(SYSCTL_HANDLER_ARGS)
102{
103	struct kdb_dbbe *be, **iter;
104	char *avail, *p;
105	ssize_t len, sz;
106	int error;
107
108	sz = 0;
109	SET_FOREACH(iter, kdb_dbbe_set) {
110		be = *iter;
111		if (be->dbbe_active == 0)
112			sz += strlen(be->dbbe_name) + 1;
113	}
114	sz++;
115	avail = malloc(sz, M_TEMP, M_WAITOK);
116	p = avail;
117	*p = '\0';
118
119	SET_FOREACH(iter, kdb_dbbe_set) {
120		be = *iter;
121		if (be->dbbe_active == 0) {
122			len = snprintf(p, sz, "%s ", be->dbbe_name);
123			p += len;
124			sz -= len;
125		}
126	}
127	KASSERT(sz >= 0, ("%s", __func__));
128	error = sysctl_handle_string(oidp, avail, 0, req);
129	free(avail, M_TEMP);
130	return (error);
131}
132
133static int
134kdb_sysctl_current(SYSCTL_HANDLER_ARGS)
135{
136	char buf[16];
137	int error;
138
139	if (kdb_dbbe != NULL) {
140		strncpy(buf, kdb_dbbe->dbbe_name, sizeof(buf));
141		buf[sizeof(buf) - 1] = '\0';
142	} else
143		*buf = '\0';
144	error = sysctl_handle_string(oidp, buf, sizeof(buf), req);
145	if (error != 0 || req->newptr == NULL)
146		return (error);
147	if (kdb_active)
148		return (EBUSY);
149	return (kdb_dbbe_select(buf));
150}
151
152static int
153kdb_sysctl_enter(SYSCTL_HANDLER_ARGS)
154{
155	int error, i;
156
157	error = sysctl_wire_old_buffer(req, sizeof(int));
158	if (error == 0) {
159		i = 0;
160		error = sysctl_handle_int(oidp, &i, 0, req);
161	}
162	if (error != 0 || req->newptr == NULL)
163		return (error);
164	if (kdb_active)
165		return (EBUSY);
166	kdb_enter("sysctl debug.kdb.enter");
167	return (0);
168}
169
170static int
171kdb_sysctl_panic(SYSCTL_HANDLER_ARGS)
172{
173	int error, i;
174
175	error = sysctl_wire_old_buffer(req, sizeof(int));
176	if (error == 0) {
177		i = 0;
178		error = sysctl_handle_int(oidp, &i, 0, req);
179	}
180	if (error != 0 || req->newptr == NULL)
181		return (error);
182	panic("kdb_sysctl_panic");
183	return (0);
184}
185
186static int
187kdb_sysctl_trap(SYSCTL_HANDLER_ARGS)
188{
189	int error, i;
190	int *addr = (int *)0x10;
191
192	error = sysctl_wire_old_buffer(req, sizeof(int));
193	if (error == 0) {
194		i = 0;
195		error = sysctl_handle_int(oidp, &i, 0, req);
196	}
197	if (error != 0 || req->newptr == NULL)
198		return (error);
199	return (*addr);
200}
201
202static int
203kdb_sysctl_trap_code(SYSCTL_HANDLER_ARGS)
204{
205	int error, i;
206	void (*fp)(u_int, u_int, u_int) = (void *)0xdeadc0de;
207
208	error = sysctl_wire_old_buffer(req, sizeof(int));
209	if (error == 0) {
210		i = 0;
211		error = sysctl_handle_int(oidp, &i, 0, req);
212	}
213	if (error != 0 || req->newptr == NULL)
214		return (error);
215	(*fp)(0x11111111, 0x22222222, 0x33333333);
216	return (0);
217}
218
219/*
220 * Solaris implements a new BREAK which is initiated by a character sequence
221 * CR ~ ^b which is similar to a familiar pattern used on Sun servers by the
222 * Remote Console.
223 *
224 * Note that this function may be called from almost anywhere, with interrupts
225 * disabled and with unknown locks held, so it must not access data other than
226 * its arguments.  Its up to the caller to ensure that the state variable is
227 * consistent.
228 */
229
230#define	KEY_CR		13	/* CR '\r' */
231#define	KEY_TILDE	126	/* ~ */
232#define	KEY_CRTLB	2	/* ^B */
233
234int
235kdb_alt_break(int key, int *state)
236{
237	int brk;
238
239	brk = 0;
240	switch (key) {
241	case KEY_CR:
242		*state = KEY_TILDE;
243		break;
244	case KEY_TILDE:
245		*state = (*state == KEY_TILDE) ? KEY_CRTLB : 0;
246		break;
247	case KEY_CRTLB:
248		if (*state == KEY_CRTLB)
249			brk = 1;
250		/* FALLTHROUGH */
251	default:
252		*state = 0;
253		break;
254	}
255	return (brk);
256}
257
258/*
259 * Print a backtrace of the calling thread. The backtrace is generated by
260 * the selected debugger, provided it supports backtraces. If no debugger
261 * is selected or the current debugger does not support backtraces, this
262 * function silently returns.
263 */
264
265void
266kdb_backtrace()
267{
268
269	if (kdb_dbbe != NULL && kdb_dbbe->dbbe_trace != NULL) {
270		printf("KDB: stack backtrace:\n");
271		kdb_dbbe->dbbe_trace();
272	}
273}
274
275/*
276 * Set/change the current backend.
277 */
278
279int
280kdb_dbbe_select(const char *name)
281{
282	struct kdb_dbbe *be, **iter;
283
284	SET_FOREACH(iter, kdb_dbbe_set) {
285		be = *iter;
286		if (be->dbbe_active == 0 && strcmp(be->dbbe_name, name) == 0) {
287			kdb_dbbe = be;
288			return (0);
289		}
290	}
291	return (EINVAL);
292}
293
294/*
295 * Enter the currently selected debugger. If a message has been provided,
296 * it is printed first. If the debugger does not support the enter method,
297 * it is entered by using breakpoint(), which enters the debugger through
298 * kdb_trap().
299 */
300
301void
302kdb_enter(const char *msg)
303{
304
305	if (kdb_dbbe != NULL && kdb_active == 0) {
306		if (msg != NULL)
307			printf("KDB: enter: %s\n", msg);
308		breakpoint();
309	}
310}
311
312/*
313 * Initialize the kernel debugger interface.
314 */
315
316void
317kdb_init()
318{
319	struct kdb_dbbe *be, **iter;
320	int cur_pri, pri;
321
322	kdb_active = 0;
323	kdb_dbbe = NULL;
324	cur_pri = -1;
325	SET_FOREACH(iter, kdb_dbbe_set) {
326		be = *iter;
327		pri = (be->dbbe_init != NULL) ? be->dbbe_init() : -1;
328		be->dbbe_active = (pri >= 0) ? 0 : -1;
329		if (pri > cur_pri) {
330			cur_pri = pri;
331			kdb_dbbe = be;
332		}
333	}
334	if (kdb_dbbe != NULL) {
335		printf("KDB: debugger backends:");
336		SET_FOREACH(iter, kdb_dbbe_set) {
337			be = *iter;
338			if (be->dbbe_active == 0)
339				printf(" %s", be->dbbe_name);
340		}
341		printf("\n");
342		printf("KDB: current backend: %s\n",
343		    kdb_dbbe->dbbe_name);
344	}
345}
346
347/*
348 * Handle contexts.
349 */
350
351void *
352kdb_jmpbuf(jmp_buf new)
353{
354	void *old;
355
356	old = kdb_jmpbufp;
357	kdb_jmpbufp = new;
358	return (old);
359}
360
361void
362kdb_reenter(void)
363{
364
365	if (!kdb_active || kdb_jmpbufp == NULL)
366		return;
367
368	longjmp(kdb_jmpbufp, 1);
369	/* NOTREACHED */
370}
371
372/*
373 * Thread related support functions.
374 */
375
376struct pcb *
377kdb_thr_ctx(struct thread *thr)
378{
379#if defined(SMP) && defined(KDB_STOPPEDPCB)
380	struct pcpu *pc;
381#endif
382
383	if (thr == curthread)
384		return (&kdb_pcb);
385
386#if defined(SMP) && defined(KDB_STOPPEDPCB)
387	SLIST_FOREACH(pc, &cpuhead, pc_allcpu)  {
388		if (pc->pc_curthread == thr && (stopped_cpus & pc->pc_cpumask))
389			return (KDB_STOPPEDPCB(pc));
390	}
391#endif
392	return (thr->td_pcb);
393}
394
395struct thread *
396kdb_thr_first(void)
397{
398	struct proc *p;
399	struct thread *thr;
400
401	p = LIST_FIRST(&allproc);
402	while (p != NULL) {
403		if (p->p_sflag & PS_INMEM) {
404			thr = FIRST_THREAD_IN_PROC(p);
405			if (thr != NULL)
406				return (thr);
407		}
408		p = LIST_NEXT(p, p_list);
409	}
410	return (NULL);
411}
412
413struct thread *
414kdb_thr_from_pid(pid_t pid)
415{
416	struct proc *p;
417
418	p = LIST_FIRST(&allproc);
419	while (p != NULL) {
420		if (p->p_sflag & PS_INMEM && p->p_pid == pid)
421			return (FIRST_THREAD_IN_PROC(p));
422		p = LIST_NEXT(p, p_list);
423	}
424	return (NULL);
425}
426
427struct thread *
428kdb_thr_lookup(lwpid_t tid)
429{
430	struct thread *thr;
431
432	thr = kdb_thr_first();
433	while (thr != NULL && thr->td_tid != tid)
434		thr = kdb_thr_next(thr);
435	return (thr);
436}
437
438struct thread *
439kdb_thr_next(struct thread *thr)
440{
441	struct proc *p;
442
443	p = thr->td_proc;
444	thr = TAILQ_NEXT(thr, td_plist);
445	do {
446		if (thr != NULL)
447			return (thr);
448		p = LIST_NEXT(p, p_list);
449		if (p != NULL && (p->p_sflag & PS_INMEM))
450			thr = FIRST_THREAD_IN_PROC(p);
451	} while (p != NULL);
452	return (NULL);
453}
454
455int
456kdb_thr_select(struct thread *thr)
457{
458	if (thr == NULL)
459		return (EINVAL);
460	kdb_thread = thr;
461	kdb_thrctx = kdb_thr_ctx(thr);
462	return (0);
463}
464
465/*
466 * Enter the debugger due to a trap.
467 */
468
469int
470kdb_trap(int type, int code, struct trapframe *tf)
471{
472	register_t intr;
473#ifdef SMP
474	int did_stop_cpus;
475#endif
476	int handled;
477
478	if (kdb_dbbe == NULL || kdb_dbbe->dbbe_trap == NULL)
479		return (0);
480
481	/* We reenter the debugger through kdb_reenter(). */
482	if (kdb_active)
483		return (0);
484
485	intr = intr_disable();
486
487#ifdef SMP
488	if ((did_stop_cpus = kdb_stop_cpus) != 0)
489		stop_cpus(PCPU_GET(other_cpus));
490#endif
491
492	kdb_active++;
493
494	kdb_frame = tf;
495
496	/* Let MD code do its thing first... */
497	kdb_cpu_trap(type, code);
498
499	makectx(tf, &kdb_pcb);
500	kdb_thr_select(curthread);
501
502	handled = kdb_dbbe->dbbe_trap(type, code);
503
504	kdb_active--;
505
506#ifdef SMP
507	if (did_stop_cpus)
508		restart_cpus(stopped_cpus);
509#endif
510
511	intr_restore(intr);
512
513	return (handled);
514}
515