39#include <sys/kernel.h>
40#include <sys/malloc.h>
47#include <sys/sysctl.h>
49#include <machine/kdb.h>
50#include <machine/pcb.h>
53#include <machine/smp.h>
64#ifdef BREAK_TO_DEBUGGER
65#define KDB_BREAK_TO_DEBUGGER 1
67#define KDB_BREAK_TO_DEBUGGER 0
70#ifdef ALT_BREAK_TO_DEBUGGER
71#define KDB_ALT_BREAK_TO_DEBUGGER 1
73#define KDB_ALT_BREAK_TO_DEBUGGER 0
90static SYSCTL_NODE(_debug, OID_AUTO, kdb, CTLFLAG_RW | CTLFLAG_MPSAFE, NULL,
94 CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, 0,
96 "list of available KDB backends");
99 CTLTYPE_STRING | CTLFLAG_RW | CTLFLAG_MPSAFE, NULL, 0,
101 "currently selected KDB backend");
104 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_SECURE | CTLFLAG_MPSAFE, NULL, 0,
106 "set to enter the debugger");
109 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_SECURE | CTLFLAG_MPSAFE, NULL, 0,
111 "set to panic the kernel");
114 CTLTYPE_STRING | CTLFLAG_RW | CTLFLAG_SECURE | CTLFLAG_MPSAFE, NULL, 0,
116 "trigger a kernel panic, using the provided string as the panic message");
119 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_SECURE | CTLFLAG_MPSAFE, NULL, 0,
121 "set to cause a page fault via data access");
124 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_SECURE | CTLFLAG_MPSAFE, NULL, 0,
126 "set to cause a page fault via code access");
129 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_SECURE | CTLFLAG_MPSAFE, NULL, 0,
131 "set to cause a stack overflow");
134 CTLFLAG_RWTUN | CTLFLAG_SECURE,
138 CTLFLAG_RWTUN | CTLFLAG_SECURE,
154 SET_FOREACH(iter, kdb_dbbe_set) {
155 if ((*iter)->dbbe_active == 0)
174 if (error != 0 || req->newptr == NULL)
191 if (error != 0 || req->newptr == NULL)
195 kdb_enter(KDB_WHY_SYSCTL,
"sysctl debug.kdb.enter");
209 if (error != 0 || req->newptr == NULL)
211 panic(
"kdb_sysctl_panic");
219 static char buf[256];
223 if (error != 0 || req->newptr == NULL)
233 int *
addr = (
int *)0x10;
240 if (error != 0 || req->newptr == NULL)
249 void (*fp)(u_int, u_int, u_int) = (
void *)0xdeadc0de;
256 if (error != 0 || req->newptr == NULL)
258 (*fp)(0x11111111, 0x22222222, 0x33333333);
270 *x += PCPU_GET(cpuid) / 1000000;
284 if (error != 0 || req->newptr == NULL)
303 printf(
"KDB: reboot requested\n");
336 kdb_enter(KDB_WHY_BREAK,
"Break to debugger");
337 return (KDB_REQ_DEBUGGER);
361 brk = KDB_REQ_DEBUGGER;
365 brk = KDB_REQ_REBOOT;
384 case KDB_REQ_DEBUGGER:
387 kdb_enter(KDB_WHY_BREAK,
"Break to debugger");
433 printf(
"KDB: stack backtrace:\n");
440 printf(
"KDB: stack backtrace:\n");
457 printf(
"KDB: stack backtrace of thread %d:\n", td->td_tid);
464 printf(
"KDB: stack backtrace of thread %d:\n", td->td_tid);
465 if (stack_save_td(&
st, td) == 0)
479 SET_FOREACH(iter, kdb_dbbe_set) {
481 if (be->dbbe_active == 0 && strcmp(be->dbbe_name,
name) == 0) {
503 printf(
"KDB: enter: %s\n", msg);
522 SET_FOREACH(iter, kdb_dbbe_set) {
524 pri = (be->dbbe_init != NULL) ? be->dbbe_init() : -1;
525 be->dbbe_active = (pri >= 0) ? 0 : -1;
532 printf(
"KDB: debugger backends:");
533 SET_FOREACH(iter, kdb_dbbe_set) {
535 if (be->dbbe_active == 0)
536 printf(
" %s", be->dbbe_name);
539 printf(
"KDB: current backend: %s\n",
564 printf(
"KDB: reentering\n");
587#if defined(SMP) && defined(KDB_STOPPEDPCB)
591 if (thr == curthread)
594#if defined(SMP) && defined(KDB_STOPPEDPCB)
595 STAILQ_FOREACH(pc, &cpuhead, pc_allcpu) {
596 if (pc->pc_curthread == thr &&
597 CPU_ISSET(pc->pc_cpuid, &stopped_cpus))
598 return (KDB_STOPPEDPCB(pc));
601 return (thr->td_pcb);
615 for (i = 0; i <=
pidhash; i++) {
617 thr = FIRST_THREAD_IN_PROC(p);
630 LIST_FOREACH(p, PIDHASH(pid), p_hash) {
632 return (FIRST_THREAD_IN_PROC(p));
643 while (thr != NULL && thr->td_tid != tid)
655 thr = TAILQ_NEXT(thr, td_plist);
662 p = LIST_NEXT(p, p_hash);
668 thr = FIRST_THREAD_IN_PROC(p);
699 if (be == NULL || be->dbbe_trap == NULL)
706 intr = intr_disable();
708 if (!SCHEDULER_STOPPED()) {
711 CPU_ANDNOT(&other_cpus, &other_cpus, &stopped_cpus);
712 CPU_CLR(PCPU_GET(cpuid), &other_cpus);
713 stop_cpus_hard(other_cpus);
715 curthread->td_stopsched = 1;
725 kdb_cpu_trap(
type, code);
733 handled = be->dbbe_trap(
type, code);
737 if (be == NULL || be->dbbe_trap == NULL)
739 printf(
"Switching to %s back-end\n", be->dbbe_name);
747 curthread->td_stopsched = 0;
749 CPU_AND(&other_cpus, &other_cpus, &stopped_cpus);
750 restart_cpus(other_cpus);
device_property_type_t type
static struct bt_table st
struct pidhashhead * pidhashtbl
void shutdown_nice(int howto)
void panic(const char *fmt,...)
int sysctl_wire_old_buffer(struct sysctl_req *req, size_t len)
int sysctl_handle_int(SYSCTL_HANDLER_ARGS)
int sysctl_handle_string(SYSCTL_HANDLER_ARGS)
struct sbuf * sbuf_new_for_sysctl(struct sbuf *s, char *buf, int length, struct sysctl_req *req)
int kdb_thr_select(struct thread *thr)
@ KDB_ALT_BREAK_SEEN_NONE
@ KDB_ALT_BREAK_SEEN_CR_TILDE
static int kdb_break_to_debugger
KDB_BACKEND(null, NULL, NULL, NULL, NULL)
struct thread * kdb_thr_lookup(lwpid_t tid)
static int kdb_sysctl_enter(SYSCTL_HANDLER_ARGS)
SYSCTL_PROC(_debug_kdb, OID_AUTO, available, CTLTYPE_STRING|CTLFLAG_RD|CTLFLAG_MPSAFE, NULL, 0, kdb_sysctl_available, "A", "list of available KDB backends")
void kdb_reenter_silent(void)
#define KDB_ALT_BREAK_TO_DEBUGGER
static int kdb_sysctl_trap(SYSCTL_HANDLER_ARGS)
static int kdb_sysctl_current(SYSCTL_HANDLER_ARGS)
struct trapframe * kdb_frame
u_char __read_frequently kdb_active
struct thread * kdb_thread
static int kdb_alt_break_to_debugger
const char *volatile kdb_why
#define KDB_BREAK_TO_DEBUGGER
static int kdb_sysctl_stack_overflow(SYSCTL_HANDLER_ARGS)
SYSCTL_INT(_debug_kdb, OID_AUTO, break_to_debugger, CTLFLAG_RWTUN|CTLFLAG_SECURE, &kdb_break_to_debugger, 0, "Enable break to debugger")
int kdb_alt_break(int key, int *state)
void kdb_enter(const char *why, const char *msg)
static SYSCTL_NODE(_debug, OID_AUTO, kdb, CTLFLAG_RW|CTLFLAG_MPSAFE, NULL, "KDB nodes")
int kdb_alt_break_gdb(int key, int *state)
static void * kdb_jmpbufp
struct pcb * kdb_thr_ctx(struct thread *thr)
static int kdb_alt_break_internal(int key, int *state, int force_gdb)
void kdb_backtrace_thread(struct thread *td)
static int kdb_sysctl_panic(SYSCTL_HANDLER_ARGS)
void * kdb_jmpbuf(jmp_buf new)
struct thread * kdb_thr_from_pid(pid_t pid)
static int kdb_alt_break_state(int key, int *state)
int kdb_trap(int type, int code, struct trapframe *tf)
int kdb_dbbe_select(const char *name)
static struct pcb kdb_pcb
static int kdb_sysctl_available(SYSCTL_HANDLER_ARGS)
static int kdb_sysctl_panic_str(SYSCTL_HANDLER_ARGS)
struct thread * kdb_thr_next(struct thread *thr)
struct thread * kdb_thr_first(void)
void kdb_panic(const char *msg)
static int kdb_sysctl_trap_code(SYSCTL_HANDLER_ARGS)
struct kdb_dbbe * kdb_dbbe
static void kdb_stack_overflow(volatile int *x) __noinline
int printf(const char *fmt,...)
int sbuf_finish(struct sbuf *s)
void sbuf_delete(struct sbuf *s)
int sbuf_printf(struct sbuf *s, const char *fmt,...)
void stack_zero(struct stack *st)
void stack_print_ddb(const struct stack *st)