27 #include <sys/cdefs.h>
31 #include "opt_stack.h"
33 #include <sys/param.h>
34 #include <sys/systm.h>
37 #include <sys/kernel.h>
38 #include <sys/malloc.h>
43 #include <sys/stack.h>
44 #include <sys/sysctl.h>
46 #include <machine/kdb.h>
47 #include <machine/pcb.h>
50 #include <machine/smp.h>
61 #ifdef BREAK_TO_DEBUGGER
62 #define KDB_BREAK_TO_DEBUGGER 1
64 #define KDB_BREAK_TO_DEBUGGER 0
67 #ifdef ALT_BREAK_TO_DEBUGGER
68 #define KDB_ALT_BREAK_TO_DEBUGGER 1
70 #define KDB_ALT_BREAK_TO_DEBUGGER 0
86 static SYSCTL_NODE(_debug, OID_AUTO, kdb, CTLFLAG_RW, NULL,
"KDB nodes");
88 SYSCTL_PROC(_debug_kdb, OID_AUTO, available, CTLTYPE_STRING | CTLFLAG_RD, NULL,
91 SYSCTL_PROC(_debug_kdb, OID_AUTO, current, CTLTYPE_STRING | CTLFLAG_RW, NULL,
94 SYSCTL_PROC(_debug_kdb, OID_AUTO, enter, CTLTYPE_INT | CTLFLAG_RW, NULL, 0,
100 SYSCTL_PROC(_debug_kdb, OID_AUTO, trap, CTLTYPE_INT | CTLFLAG_RW, NULL, 0,
103 SYSCTL_PROC(_debug_kdb, OID_AUTO, trap_code, CTLTYPE_INT | CTLFLAG_RW, NULL, 0,
106 SYSCTL_INT(_debug_kdb, OID_AUTO, break_to_debugger, CTLFLAG_RW |
110 SYSCTL_INT(_debug_kdb, OID_AUTO, alt_break_to_debugger,
112 "Enable alternative break to debugger");
118 const char *
volatile kdb_why = KDB_WHY_UNSET;
128 SET_FOREACH(iter, kdb_dbbe_set) {
129 if ((*iter)->dbbe_active == 0)
144 strlcpy(buf,
kdb_dbbe->dbbe_name,
sizeof(buf));
148 if (error != 0 || req->newptr == NULL)
165 if (error != 0 || req->newptr == NULL)
169 kdb_enter(KDB_WHY_SYSCTL,
"sysctl debug.kdb.enter");
183 if (error != 0 || req->newptr == NULL)
185 panic(
"kdb_sysctl_panic");
193 int *addr = (
int *)0x10;
200 if (error != 0 || req->newptr == NULL)
209 void (*fp)(u_int, u_int, u_int) = (
void *)0xdeadc0de;
216 if (error != 0 || req->newptr == NULL)
218 (*fp)(0x11111111, 0x22222222, 0x33333333);
234 printf(
"KDB: reboot requested\n");
250 #define KEY_TILDE 126
268 kdb_enter(KDB_WHY_BREAK,
"Break to debugger");
269 return (KDB_REQ_DEBUGGER);
293 brk = KDB_REQ_DEBUGGER;
297 brk = KDB_REQ_REBOOT;
316 case KDB_REQ_DEBUGGER:
319 kdb_enter(KDB_WHY_BREAK,
"Break to debugger");
366 printf(
"KDB: stack backtrace:\n");
373 printf(
"KDB: stack backtrace:\n");
390 printf(
"KDB: stack backtrace of thread %d:\n", td->td_tid);
397 printf(
"KDB: stack backtrace of thread %d:\n", td->td_tid);
399 stack_save_td(&st, td);
414 SET_FOREACH(iter, kdb_dbbe_set) {
416 if (be->dbbe_active == 0 && strcmp(be->dbbe_name, name) == 0) {
438 printf(
"KDB: enter: %s\n", msg);
458 SET_FOREACH(iter, kdb_dbbe_set) {
460 pri = (be->dbbe_init != NULL) ? be->dbbe_init() : -1;
461 be->dbbe_active = (pri >= 0) ? 0 : -1;
468 printf(
"KDB: debugger backends:");
469 SET_FOREACH(iter, kdb_dbbe_set) {
471 if (be->dbbe_active == 0)
472 printf(
" %s", be->dbbe_name);
475 printf(
"KDB: current backend: %s\n",
501 printf(
"KDB: reentering\n");
514 #if defined(SMP) && defined(KDB_STOPPEDPCB)
518 if (thr == curthread)
521 #if defined(SMP) && defined(KDB_STOPPEDPCB)
522 STAILQ_FOREACH(pc, &cpuhead, pc_allcpu) {
523 if (pc->pc_curthread == thr &&
524 CPU_ISSET(pc->pc_cpuid, &stopped_cpus))
525 return (KDB_STOPPEDPCB(pc));
528 return (thr->td_pcb);
539 if (p->p_flag & P_INMEM) {
540 thr = FIRST_THREAD_IN_PROC(p);
544 p = LIST_NEXT(p, p_list);
556 if (p->p_flag & P_INMEM && p->p_pid == pid)
557 return (FIRST_THREAD_IN_PROC(p));
558 p = LIST_NEXT(p, p_list);
569 while (thr != NULL && thr->td_tid != tid)
580 thr = TAILQ_NEXT(thr, td_plist);
584 p = LIST_NEXT(p, p_list);
585 if (p != NULL && (p->p_flag & P_INMEM))
586 thr = FIRST_THREAD_IN_PROC(p);
619 if (be == NULL || be->dbbe_trap == NULL)
626 intr = intr_disable();
629 if (!SCHEDULER_STOPPED()) {
631 CPU_CLR(PCPU_GET(cpuid), &other_cpus);
632 stop_cpus_hard(other_cpus);
643 kdb_cpu_trap(type, code);
651 handled = be->dbbe_trap(type, code);
655 if (be == NULL || be->dbbe_trap == NULL)
657 printf(
"Switching to %s back-end\n", be->dbbe_name);
666 restart_cpus(stopped_cpus);
static int kdb_alt_break_internal(int key, int *state, int force_gdb)
void kdb_backtrace_thread(struct thread *td)
static int kdb_break_to_debugger
static void * kdb_jmpbufp
int kdb_alt_break(int key, int *state)
static int kdb_sysctl_current(SYSCTL_HANDLER_ARGS)
SYSCTL_PROC(_debug_kdb, OID_AUTO, available, CTLTYPE_STRING|CTLFLAG_RD, NULL, 0, kdb_sysctl_available,"A","list of available KDB backends")
SET_DECLARE(kdb_dbbe_set, struct kdb_dbbe)
static int kdb_alt_break_state(int key, int *state)
struct thread * kdb_thr_from_pid(pid_t pid)
void panic(const char *fmt,...)
static int kdb_sysctl_enter(SYSCTL_HANDLER_ARGS)
int kdb_thr_select(struct thread *thr)
#define KDB_BREAK_TO_DEBUGGER
static int kdb_sysctl_panic(SYSCTL_HANDLER_ARGS)
int kdb_trap(int type, int code, struct trapframe *tf)
static int kdb_sysctl_trap(SYSCTL_HANDLER_ARGS)
int sysctl_handle_string(SYSCTL_HANDLER_ARGS)
struct thread * kdb_thr_next(struct thread *thr)
SYSCTL_INT(_debug_kdb, OID_AUTO, break_to_debugger, CTLFLAG_RW|CTLFLAG_TUN,&kdb_break_to_debugger, 0,"Enable break to debugger")
int kdb_dbbe_select(const char *name)
int kdb_alt_break_gdb(int key, int *state)
void * kdb_jmpbuf(jmp_buf new)
TUNABLE_INT("debug.kdb.break_to_debugger",&kdb_break_to_debugger)
static int kdb_alt_break_to_debugger
void shutdown_nice(int howto)
struct thread * kdb_thr_lookup(lwpid_t tid)
void stack_zero(struct stack *st)
int sbuf_printf(struct sbuf *s, const char *fmt,...)
struct pcb * kdb_thr_ctx(struct thread *thr)
int sysctl_handle_int(SYSCTL_HANDLER_ARGS)
void kdb_panic(const char *msg)
struct thread * kdb_thread
KDB_BACKEND(null, NULL, NULL, NULL, NULL)
void kdb_enter(const char *why, const char *msg)
int printf(const char *fmt,...)
#define KDB_ALT_BREAK_TO_DEBUGGER
struct thread * kdb_thr_first(void)
void sbuf_delete(struct sbuf *s)
int sysctl_wire_old_buffer(struct sysctl_req *req, size_t len)
const char *volatile kdb_why
int sbuf_finish(struct sbuf *s)
static int kdb_sysctl_trap_code(SYSCTL_HANDLER_ARGS)
static int kdb_sysctl_available(SYSCTL_HANDLER_ARGS)
void stack_print_ddb(struct stack *st)
struct kdb_dbbe * kdb_dbbe
struct trapframe * kdb_frame
static SYSCTL_NODE(_debug, OID_AUTO, kdb, CTLFLAG_RW, NULL,"KDB nodes")
static struct pcb kdb_pcb
struct sbuf * sbuf_new_for_sysctl(struct sbuf *s, char *buf, int length, struct sysctl_req *req)