subr_kdb.c revision 151634
1184610Salfred/*-
2184610Salfred * Copyright (c) 2004 The FreeBSD Project
3184610Salfred * All rights reserved.
4184610Salfred *
5184610Salfred * Redistribution and use in source and binary forms, with or without
6184610Salfred * modification, are permitted provided that the following conditions
7184610Salfred * are met:
8189002Sed *
9184610Salfred * 1. Redistributions of source code must retain the above copyright
10184610Salfred *    notice, this list of conditions and the following disclaimer.
11184610Salfred * 2. Redistributions in binary form must reproduce the above copyright
12184610Salfred *    notice, this list of conditions and the following disclaimer in the
13184610Salfred *    documentation and/or other materials provided with the distribution.
14184610Salfred *
15184610Salfred * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
16184610Salfred * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17184610Salfred * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18184610Salfred * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
19184610Salfred * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20184610Salfred * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21184610Salfred * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22184610Salfred * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23184610Salfred * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24184610Salfred * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25184610Salfred */
26184610Salfred
27184610Salfred#include <sys/cdefs.h>
28184610Salfred__FBSDID("$FreeBSD: head/sys/kern/subr_kdb.c 151634 2005-10-24 21:04:19Z jhb $");
29184610Salfred
30184610Salfred#include "opt_kdb.h"
31191746Sthompsa
32191746Sthompsa#include <sys/param.h>
33191746Sthompsa#include <sys/systm.h>
34191746Sthompsa#include <sys/kdb.h>
35191746Sthompsa#include <sys/kernel.h>
36191746Sthompsa#include <sys/malloc.h>
37191746Sthompsa#include <sys/pcpu.h>
38191746Sthompsa#include <sys/proc.h>
39191746Sthompsa#include <sys/smp.h>
40191746Sthompsa#include <sys/sysctl.h>
41191746Sthompsa
42191746Sthompsa#include <machine/kdb.h>
43191746Sthompsa#include <machine/pcb.h>
44191746Sthompsa
45184610Salfred#ifdef SMP
46191746Sthompsa#if defined (__i386__) || defined(__amd64__)
47191746Sthompsa#define	HAVE_STOPPEDPCBS
48191746Sthompsa#include <machine/smp.h>
49191746Sthompsa#endif
50191746Sthompsa#endif
51191746Sthompsa
52191746Sthompsaint kdb_active = 0;
53191746Sthompsavoid *kdb_jmpbufp = NULL;
54191746Sthompsastruct kdb_dbbe *kdb_dbbe = NULL;
55191746Sthompsastruct pcb kdb_pcb;
56191746Sthompsastruct pcb *kdb_thrctx = NULL;
57191746Sthompsastruct thread *kdb_thread = NULL;
58191746Sthompsastruct trapframe *kdb_frame = NULL;
59191746Sthompsa
60191746SthompsaKDB_BACKEND(null, NULL, NULL, NULL);
61191746SthompsaSET_DECLARE(kdb_dbbe_set, struct kdb_dbbe);
62191746Sthompsa
63191746Sthompsastatic int kdb_sysctl_available(SYSCTL_HANDLER_ARGS);
64191746Sthompsastatic int kdb_sysctl_current(SYSCTL_HANDLER_ARGS);
65191746Sthompsastatic int kdb_sysctl_enter(SYSCTL_HANDLER_ARGS);
66191746Sthompsa
67191746SthompsaSYSCTL_NODE(_debug, OID_AUTO, kdb, CTLFLAG_RW, NULL, "KDB nodes");
68191746Sthompsa
69206358SrpauloSYSCTL_PROC(_debug_kdb, OID_AUTO, available, CTLTYPE_STRING | CTLFLAG_RD, 0, 0,
70191746Sthompsa    kdb_sysctl_available, "A", "list of available KDB backends");
71191746Sthompsa
72194677SthompsaSYSCTL_PROC(_debug_kdb, OID_AUTO, current, CTLTYPE_STRING | CTLFLAG_RW, 0, 0,
73191746Sthompsa    kdb_sysctl_current, "A", "currently selected KDB backend");
74184610Salfred
75194677SthompsaSYSCTL_PROC(_debug_kdb, OID_AUTO, enter, CTLTYPE_INT | CTLFLAG_RW, 0, 0,
76194677Sthompsa    kdb_sysctl_enter, "I", "set to enter the debugger");
77191746Sthompsa
78188942Sthompsa/*
79188942Sthompsa * Flag indicating whether or not to IPI the other CPUs to stop them on
80184610Salfred * entering the debugger.  Sometimes, this will result in a deadlock as
81207077Sthompsa * stop_cpus() waits for the other cpus to stop, so we allow it to be
82184610Salfred * disabled.
83184610Salfred */
84192502Sthompsa#ifdef SMP
85192502Sthompsastatic int kdb_stop_cpus = 1;
86184610SalfredSYSCTL_INT(_debug_kdb, OID_AUTO, stop_cpus, CTLTYPE_INT | CTLFLAG_RW,
87184610Salfred    &kdb_stop_cpus, 0, "");
88184610SalfredTUNABLE_INT("debug.kdb.stop_cpus", &kdb_stop_cpus);
89188417Sthompsa#endif
90188417Sthompsa
91188417Sthompsastatic int
92184610Salfredkdb_sysctl_available(SYSCTL_HANDLER_ARGS)
93188417Sthompsa{
94223486Shselasky	struct kdb_dbbe *be, **iter;
95201028Sthompsa	char *avail, *p;
96201028Sthompsa	ssize_t len, sz;
97201028Sthompsa	int error;
98201028Sthompsa
99201028Sthompsa	sz = 0;
100201028Sthompsa	SET_FOREACH(iter, kdb_dbbe_set) {
101201028Sthompsa		be = *iter;
102201028Sthompsa		if (be->dbbe_active == 0)
103201028Sthompsa			sz += strlen(be->dbbe_name) + 1;
104201028Sthompsa	}
105201028Sthompsa	sz++;
106201028Sthompsa	avail = malloc(sz, M_TEMP, M_WAITOK);
107201028Sthompsa	p = avail;
108201028Sthompsa	*p = '\0';
109201028Sthompsa
110201028Sthompsa	SET_FOREACH(iter, kdb_dbbe_set) {
111201028Sthompsa		be = *iter;
112201028Sthompsa		if (be->dbbe_active == 0) {
113201028Sthompsa			len = snprintf(p, sz, "%s ", be->dbbe_name);
114201028Sthompsa			p += len;
115201028Sthompsa			sz -= len;
116201028Sthompsa		}
117201028Sthompsa	}
118201028Sthompsa	KASSERT(sz >= 0, ("%s", __func__));
119201028Sthompsa	error = sysctl_handle_string(oidp, avail, 0, req);
120201028Sthompsa	free(avail, M_TEMP);
121201028Sthompsa	return (error);
122201028Sthompsa}
123201028Sthompsa
124201028Sthompsastatic int
125201028Sthompsakdb_sysctl_current(SYSCTL_HANDLER_ARGS)
126188417Sthompsa{
127184610Salfred	char buf[16];
128193045Sthompsa	int error;
129193045Sthompsa
130184610Salfred	if (kdb_dbbe != NULL) {
131193045Sthompsa		strncpy(buf, kdb_dbbe->dbbe_name, sizeof(buf));
132192984Sthompsa		buf[sizeof(buf) - 1] = '\0';
133185948Sthompsa	} else
134188417Sthompsa		*buf = '\0';
135188417Sthompsa	error = sysctl_handle_string(oidp, buf, sizeof(buf), req);
136188417Sthompsa	if (error != 0 || req->newptr == NULL)
137188417Sthompsa		return (error);
138188417Sthompsa	if (kdb_active)
139188419Sthompsa		return (EBUSY);
140188419Sthompsa	return (kdb_dbbe_select(buf));
141188417Sthompsa}
142188417Sthompsa
143188417Sthompsastatic int
144188417Sthompsakdb_sysctl_enter(SYSCTL_HANDLER_ARGS)
145188417Sthompsa{
146188417Sthompsa	int error, i;
147188417Sthompsa
148188417Sthompsa	error = sysctl_wire_old_buffer(req, sizeof(int));
149188417Sthompsa	if (error == 0) {
150188417Sthompsa		i = 0;
151188417Sthompsa		error = sysctl_handle_int(oidp, &i, 0, req);
152188417Sthompsa	}
153188417Sthompsa	if (error != 0 || req->newptr == NULL)
154188417Sthompsa		return (error);
155188417Sthompsa	if (kdb_active)
156188417Sthompsa		return (EBUSY);
157188417Sthompsa	kdb_enter("sysctl debug.kdb.enter");
158188417Sthompsa	return (0);
159188417Sthompsa}
160188417Sthompsa
161188417Sthompsa/*
162188417Sthompsa * Solaris implements a new BREAK which is initiated by a character sequence
163188417Sthompsa * CR ~ ^b which is similar to a familiar pattern used on Sun servers by the
164188417Sthompsa * Remote Console.
165188417Sthompsa *
166188417Sthompsa * Note that this function may be called from almost anywhere, with interrupts
167188417Sthompsa * disabled and with unknown locks held, so it must not access data other than
168188417Sthompsa * its arguments.  Its up to the caller to ensure that the state variable is
169188417Sthompsa * consistent.
170188417Sthompsa */
171188417Sthompsa
172192468Ssam#define	KEY_CR		13	/* CR '\r' */
173188417Sthompsa#define	KEY_TILDE	126	/* ~ */
174188417Sthompsa#define	KEY_CRTLB	2	/* ^B */
175188417Sthompsa
176188417Sthompsaint
177188417Sthompsakdb_alt_break(int key, int *state)
178188417Sthompsa{
179189123Sthompsa	int brk;
180191746Sthompsa
181188417Sthompsa	brk = 0;
182188417Sthompsa	switch (key) {
183188417Sthompsa	case KEY_CR:
184188417Sthompsa		*state = KEY_TILDE;
185188417Sthompsa		break;
186191746Sthompsa	case KEY_TILDE:
187188417Sthompsa		*state = (*state == KEY_TILDE) ? KEY_CRTLB : 0;
188191746Sthompsa		break;
189188417Sthompsa	case KEY_CRTLB:
190188417Sthompsa		if (*state == KEY_CRTLB)
191206358Srpaulo			brk = 1;
192188417Sthompsa		/* FALLTHROUGH */
193206358Srpaulo	default:
194206358Srpaulo		*state = 0;
195188619Sthompsa		break;
196184610Salfred	}
197184610Salfred	return (brk);
198188417Sthompsa}
199184610Salfred
200188417Sthompsa/*
201188417Sthompsa * Print a backtrace of the calling thread. The backtrace is generated by
202188417Sthompsa * the selected debugger, provided it supports backtraces. If no debugger
203188417Sthompsa * is selected or the current debugger does not support backtraces, this
204188417Sthompsa * function silently returns.
205188417Sthompsa */
206188417Sthompsa
207188417Sthompsavoid
208188417Sthompsakdb_backtrace()
209188417Sthompsa{
210188417Sthompsa
211188417Sthompsa	if (kdb_dbbe != NULL && kdb_dbbe->dbbe_trace != NULL) {
212188417Sthompsa		printf("KDB: stack backtrace:\n");
213188417Sthompsa		kdb_dbbe->dbbe_trace();
214188417Sthompsa	}
215188417Sthompsa}
216188417Sthompsa
217188417Sthompsa/*
218188417Sthompsa * Set/change the current backend.
219188417Sthompsa */
220188417Sthompsa
221184610Salfredint
222184610Salfredkdb_dbbe_select(const char *name)
223184610Salfred{
224184610Salfred	struct kdb_dbbe *be, **iter;
225184610Salfred
226188417Sthompsa	SET_FOREACH(iter, kdb_dbbe_set) {
227184610Salfred		be = *iter;
228184610Salfred		if (be->dbbe_active == 0 && strcmp(be->dbbe_name, name) == 0) {
229188417Sthompsa			kdb_dbbe = be;
230188417Sthompsa			return (0);
231188417Sthompsa		}
232188417Sthompsa	}
233188417Sthompsa	return (EINVAL);
234188417Sthompsa}
235188417Sthompsa
236188417Sthompsa/*
237188417Sthompsa * Enter the currently selected debugger. If a message has been provided,
238188417Sthompsa * it is printed first. If the debugger does not support the enter method,
239188417Sthompsa * it is entered by using breakpoint(), which enters the debugger through
240188417Sthompsa * kdb_trap().
241188417Sthompsa */
242188417Sthompsa
243188417Sthompsavoid
244188417Sthompsakdb_enter(const char *msg)
245188417Sthompsa{
246188417Sthompsa
247188417Sthompsa	if (kdb_dbbe != NULL && kdb_active == 0) {
248188417Sthompsa		if (msg != NULL)
249188417Sthompsa			printf("KDB: enter: %s\n", msg);
250188417Sthompsa		breakpoint();
251188417Sthompsa	}
252188417Sthompsa}
253188417Sthompsa
254188417Sthompsa/*
255188417Sthompsa * Initialize the kernel debugger interface.
256188417Sthompsa */
257188417Sthompsa
258188417Sthompsavoid
259188417Sthompsakdb_init()
260188417Sthompsa{
261188417Sthompsa	struct kdb_dbbe *be, **iter;
262184610Salfred	int cur_pri, pri;
263184610Salfred
264184610Salfred	kdb_active = 0;
265184610Salfred	kdb_dbbe = NULL;
266184610Salfred	cur_pri = -1;
267184610Salfred	SET_FOREACH(iter, kdb_dbbe_set) {
268184610Salfred		be = *iter;
269184610Salfred		pri = (be->dbbe_init != NULL) ? be->dbbe_init() : -1;
270184610Salfred		be->dbbe_active = (pri >= 0) ? 0 : -1;
271184610Salfred		if (pri > cur_pri) {
272184610Salfred			cur_pri = pri;
273184610Salfred			kdb_dbbe = be;
274184610Salfred		}
275184610Salfred	}
276184610Salfred	if (kdb_dbbe != NULL) {
277184610Salfred		printf("KDB: debugger backends:");
278184610Salfred		SET_FOREACH(iter, kdb_dbbe_set) {
279184610Salfred			be = *iter;
280184610Salfred			if (be->dbbe_active == 0)
281184610Salfred				printf(" %s", be->dbbe_name);
282184610Salfred		}
283184610Salfred		printf("\n");
284184610Salfred		printf("KDB: current backend: %s\n",
285184610Salfred		    kdb_dbbe->dbbe_name);
286184610Salfred	}
287184610Salfred}
288184610Salfred
289184610Salfred/*
290184610Salfred * Handle contexts.
291184610Salfred */
292184610Salfred
293184610Salfredvoid *
294184610Salfredkdb_jmpbuf(jmp_buf new)
295184610Salfred{
296184610Salfred	void *old;
297184610Salfred
298184610Salfred	old = kdb_jmpbufp;
299184610Salfred	kdb_jmpbufp = new;
300184610Salfred	return (old);
301184610Salfred}
302184610Salfred
303184610Salfredvoid
304184610Salfredkdb_reenter(void)
305184610Salfred{
306184610Salfred
307184610Salfred	if (!kdb_active || kdb_jmpbufp == NULL)
308184610Salfred		return;
309184610Salfred
310184610Salfred	longjmp(kdb_jmpbufp, 1);
311188417Sthompsa	/* NOTREACHED */
312188417Sthompsa}
313188417Sthompsa
314188417Sthompsa/*
315188417Sthompsa * Thread related support functions.
316188417Sthompsa */
317188417Sthompsa
318188417Sthompsastruct pcb *
319188417Sthompsakdb_thr_ctx(struct thread *thr)
320188417Sthompsa{
321188417Sthompsa#ifdef HAVE_STOPPEDPCBS
322188417Sthompsa	struct pcpu *pc;
323188417Sthompsa	u_int cpuid;
324188417Sthompsa#endif
325188417Sthompsa
326188417Sthompsa	if (thr == curthread)
327188417Sthompsa		return (&kdb_pcb);
328188417Sthompsa
329188417Sthompsa#ifdef HAVE_STOPPEDPCBS
330188417Sthompsa	SLIST_FOREACH(pc, &cpuhead, pc_allcpu)  {
331184610Salfred		cpuid = pc->pc_cpuid;
332188417Sthompsa		if (pc->pc_curthread == thr && (stopped_cpus & (1 << cpuid)))
333188417Sthompsa			return (&stoppcbs[cpuid]);
334188417Sthompsa	}
335188417Sthompsa#endif
336188417Sthompsa	return (thr->td_pcb);
337188417Sthompsa}
338188417Sthompsa
339188417Sthompsastruct thread *
340184610Salfredkdb_thr_first(void)
341188417Sthompsa{
342188417Sthompsa	struct proc *p;
343188417Sthompsa	struct thread *thr;
344188417Sthompsa
345188417Sthompsa	p = LIST_FIRST(&allproc);
346188417Sthompsa	while (p != NULL) {
347188417Sthompsa		if (p->p_sflag & PS_INMEM) {
348188417Sthompsa			thr = FIRST_THREAD_IN_PROC(p);
349188417Sthompsa			if (thr != NULL)
350188417Sthompsa				return (thr);
351188417Sthompsa		}
352184610Salfred		p = LIST_NEXT(p, p_list);
353188417Sthompsa	}
354188417Sthompsa	return (NULL);
355188417Sthompsa}
356188417Sthompsa
357184610Salfredstruct thread *
358184610Salfredkdb_thr_from_pid(pid_t pid)
359192984Sthompsa{
360188417Sthompsa	struct proc *p;
361184610Salfred
362184610Salfred	p = LIST_FIRST(&allproc);
363184610Salfred	while (p != NULL) {
364190734Sthompsa		if (p->p_sflag & PS_INMEM && p->p_pid == pid)
365190734Sthompsa			return (FIRST_THREAD_IN_PROC(p));
366190734Sthompsa		p = LIST_NEXT(p, p_list);
367190734Sthompsa	}
368184610Salfred	return (NULL);
369188417Sthompsa}
370184610Salfred
371184610Salfredstruct thread *
372184610Salfredkdb_thr_lookup(lwpid_t tid)
373190734Sthompsa{
374190734Sthompsa	struct thread *thr;
375190734Sthompsa
376184610Salfred	thr = kdb_thr_first();
377184610Salfred	while (thr != NULL && thr->td_tid != tid)
378184610Salfred		thr = kdb_thr_next(thr);
379188417Sthompsa	return (thr);
380188417Sthompsa}
381188417Sthompsa
382184610Salfredstruct thread *
383184610Salfredkdb_thr_next(struct thread *thr)
384188417Sthompsa{
385188417Sthompsa	struct proc *p;
386188417Sthompsa
387188417Sthompsa	p = thr->td_proc;
388188417Sthompsa	thr = TAILQ_NEXT(thr, td_plist);
389188417Sthompsa	do {
390184610Salfred		if (thr != NULL)
391184610Salfred			return (thr);
392184610Salfred		p = LIST_NEXT(p, p_list);
393184610Salfred		if (p != NULL && (p->p_sflag & PS_INMEM))
394184610Salfred			thr = FIRST_THREAD_IN_PROC(p);
395184610Salfred	} while (p != NULL);
396184610Salfred	return (NULL);
397184610Salfred}
398188417Sthompsa
399188417Sthompsaint
400189275Sthompsakdb_thr_select(struct thread *thr)
401188942Sthompsa{
402184610Salfred	if (thr == NULL)
403212122Sthompsa		return (EINVAL);
404184610Salfred	kdb_thread = thr;
405184610Salfred	kdb_thrctx = kdb_thr_ctx(thr);
406188417Sthompsa	return (0);
407184610Salfred}
408192984Sthompsa
409184610Salfred/*
410192499Sthompsa * Enter the debugger due to a trap.
411184610Salfred */
412188417Sthompsa
413184610Salfredint
414188417Sthompsakdb_trap(int type, int code, struct trapframe *tf)
415184610Salfred{
416188417Sthompsa#ifdef SMP
417194228Sthompsa	int did_stop_cpus;
418184610Salfred#endif
419184610Salfred	int handled;
420184610Salfred
421188417Sthompsa	if (kdb_dbbe == NULL || kdb_dbbe->dbbe_trap == NULL)
422184610Salfred		return (0);
423192984Sthompsa
424188417Sthompsa	/* We reenter the debugger through kdb_reenter(). */
425191746Sthompsa	if (kdb_active)
426191746Sthompsa		return (0);
427191746Sthompsa
428184610Salfred	critical_enter();
429184610Salfred
430194228Sthompsa	kdb_active++;
431184610Salfred
432188417Sthompsa#ifdef SMP
433184610Salfred	if ((did_stop_cpus = kdb_stop_cpus) != 0)
434188417Sthompsa		stop_cpus(PCPU_GET(other_cpus));
435188417Sthompsa#endif
436184610Salfred
437184610Salfred	kdb_frame = tf;
438194228Sthompsa
439184610Salfred	/* Let MD code do its thing first... */
440184610Salfred	kdb_cpu_trap(type, code);
441184610Salfred
442188417Sthompsa	makectx(tf, &kdb_pcb);
443194228Sthompsa	kdb_thr_select(curthread);
444184610Salfred
445184610Salfred	handled = kdb_dbbe->dbbe_trap(type, code);
446184610Salfred
447188419Sthompsa#ifdef SMP
448188417Sthompsa	if (did_stop_cpus)
449188417Sthompsa		restart_cpus(stopped_cpus);
450184610Salfred#endif
451188417Sthompsa
452188417Sthompsa	kdb_active--;
453188417Sthompsa
454184610Salfred	critical_exit();
455191746Sthompsa
456188417Sthompsa	return (handled);
457184610Salfred}
458188419Sthompsa