FreeBSD kernel kern code
subr_kdb.c
Go to the documentation of this file.
1/*-
2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3 *
4 * Copyright (c) 2004 The FreeBSD Project
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include <sys/cdefs.h>
30__FBSDID("$FreeBSD$");
31
32#include "opt_kdb.h"
33#include "opt_stack.h"
34
35#include <sys/param.h>
36#include <sys/systm.h>
37#include <sys/cons.h>
38#include <sys/kdb.h>
39#include <sys/kernel.h>
40#include <sys/malloc.h>
41#include <sys/lock.h>
42#include <sys/pcpu.h>
43#include <sys/proc.h>
44#include <sys/sbuf.h>
45#include <sys/smp.h>
46#include <sys/stack.h>
47#include <sys/sysctl.h>
48
49#include <machine/kdb.h>
50#include <machine/pcb.h>
51
52#ifdef SMP
53#include <machine/smp.h>
54#endif
55
56u_char __read_frequently kdb_active = 0;
57static void *kdb_jmpbufp = NULL;
58struct kdb_dbbe *kdb_dbbe = NULL;
59static struct pcb kdb_pcb;
60struct pcb *kdb_thrctx = NULL;
61struct thread *kdb_thread = NULL;
62struct trapframe *kdb_frame = NULL;
63
64#ifdef BREAK_TO_DEBUGGER
65#define KDB_BREAK_TO_DEBUGGER 1
66#else
67#define KDB_BREAK_TO_DEBUGGER 0
68#endif
69
70#ifdef ALT_BREAK_TO_DEBUGGER
71#define KDB_ALT_BREAK_TO_DEBUGGER 1
72#else
73#define KDB_ALT_BREAK_TO_DEBUGGER 0
74#endif
75
78
79KDB_BACKEND(null, NULL, NULL, NULL, NULL);
80
81static int kdb_sysctl_available(SYSCTL_HANDLER_ARGS);
82static int kdb_sysctl_current(SYSCTL_HANDLER_ARGS);
83static int kdb_sysctl_enter(SYSCTL_HANDLER_ARGS);
84static int kdb_sysctl_panic(SYSCTL_HANDLER_ARGS);
85static int kdb_sysctl_panic_str(SYSCTL_HANDLER_ARGS);
86static int kdb_sysctl_trap(SYSCTL_HANDLER_ARGS);
87static int kdb_sysctl_trap_code(SYSCTL_HANDLER_ARGS);
88static int kdb_sysctl_stack_overflow(SYSCTL_HANDLER_ARGS);
89
90static SYSCTL_NODE(_debug, OID_AUTO, kdb, CTLFLAG_RW | CTLFLAG_MPSAFE, NULL,
91 "KDB nodes");
92
93SYSCTL_PROC(_debug_kdb, OID_AUTO, available,
94 CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, 0,
96 "list of available KDB backends");
97
98SYSCTL_PROC(_debug_kdb, OID_AUTO, current,
99 CTLTYPE_STRING | CTLFLAG_RW | CTLFLAG_MPSAFE, NULL, 0,
101 "currently selected KDB backend");
102
103SYSCTL_PROC(_debug_kdb, OID_AUTO, enter,
104 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_SECURE | CTLFLAG_MPSAFE, NULL, 0,
105 kdb_sysctl_enter, "I",
106 "set to enter the debugger");
107
108SYSCTL_PROC(_debug_kdb, OID_AUTO, panic,
109 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_SECURE | CTLFLAG_MPSAFE, NULL, 0,
110 kdb_sysctl_panic, "I",
111 "set to panic the kernel");
112
113SYSCTL_PROC(_debug_kdb, OID_AUTO, panic_str,
114 CTLTYPE_STRING | CTLFLAG_RW | CTLFLAG_SECURE | CTLFLAG_MPSAFE, NULL, 0,
116 "trigger a kernel panic, using the provided string as the panic message");
117
118SYSCTL_PROC(_debug_kdb, OID_AUTO, trap,
119 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_SECURE | CTLFLAG_MPSAFE, NULL, 0,
120 kdb_sysctl_trap, "I",
121 "set to cause a page fault via data access");
122
123SYSCTL_PROC(_debug_kdb, OID_AUTO, trap_code,
124 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_SECURE | CTLFLAG_MPSAFE, NULL, 0,
126 "set to cause a page fault via code access");
127
128SYSCTL_PROC(_debug_kdb, OID_AUTO, stack_overflow,
129 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_SECURE | CTLFLAG_MPSAFE, NULL, 0,
131 "set to cause a stack overflow");
132
133SYSCTL_INT(_debug_kdb, OID_AUTO, break_to_debugger,
134 CTLFLAG_RWTUN | CTLFLAG_SECURE,
135 &kdb_break_to_debugger, 0, "Enable break to debugger");
136
137SYSCTL_INT(_debug_kdb, OID_AUTO, alt_break_to_debugger,
138 CTLFLAG_RWTUN | CTLFLAG_SECURE,
139 &kdb_alt_break_to_debugger, 0, "Enable alternative break to debugger");
140
141/*
142 * Flag to indicate to debuggers why the debugger was entered.
143 */
144const char * volatile kdb_why = KDB_WHY_UNSET;
145
146static int
147kdb_sysctl_available(SYSCTL_HANDLER_ARGS)
148{
149 struct kdb_dbbe **iter;
150 struct sbuf sbuf;
151 int error;
152
153 sbuf_new_for_sysctl(&sbuf, NULL, 64, req);
154 SET_FOREACH(iter, kdb_dbbe_set) {
155 if ((*iter)->dbbe_active == 0)
156 sbuf_printf(&sbuf, "%s ", (*iter)->dbbe_name);
157 }
158 error = sbuf_finish(&sbuf);
159 sbuf_delete(&sbuf);
160 return (error);
161}
162
163static int
164kdb_sysctl_current(SYSCTL_HANDLER_ARGS)
165{
166 char buf[16];
167 int error;
168
169 if (kdb_dbbe != NULL)
170 strlcpy(buf, kdb_dbbe->dbbe_name, sizeof(buf));
171 else
172 *buf = '\0';
173 error = sysctl_handle_string(oidp, buf, sizeof(buf), req);
174 if (error != 0 || req->newptr == NULL)
175 return (error);
176 if (kdb_active)
177 return (EBUSY);
178 return (kdb_dbbe_select(buf));
179}
180
181static int
182kdb_sysctl_enter(SYSCTL_HANDLER_ARGS)
183{
184 int error, i;
185
186 error = sysctl_wire_old_buffer(req, sizeof(int));
187 if (error == 0) {
188 i = 0;
189 error = sysctl_handle_int(oidp, &i, 0, req);
190 }
191 if (error != 0 || req->newptr == NULL)
192 return (error);
193 if (kdb_active)
194 return (EBUSY);
195 kdb_enter(KDB_WHY_SYSCTL, "sysctl debug.kdb.enter");
196 return (0);
197}
198
199static int
200kdb_sysctl_panic(SYSCTL_HANDLER_ARGS)
201{
202 int error, i;
203
204 error = sysctl_wire_old_buffer(req, sizeof(int));
205 if (error == 0) {
206 i = 0;
207 error = sysctl_handle_int(oidp, &i, 0, req);
208 }
209 if (error != 0 || req->newptr == NULL)
210 return (error);
211 panic("kdb_sysctl_panic");
212 return (0);
213}
214
215static int
216kdb_sysctl_panic_str(SYSCTL_HANDLER_ARGS)
217{
218 int error;
219 static char buf[256]; /* static buffer to limit mallocs when panicing */
220
221 *buf = '\0';
222 error = sysctl_handle_string(oidp, buf, sizeof(buf), req);
223 if (error != 0 || req->newptr == NULL)
224 return (error);
225 panic("kdb_sysctl_panic: %s", buf);
226 return (0);
227}
228
229static int
230kdb_sysctl_trap(SYSCTL_HANDLER_ARGS)
231{
232 int error, i;
233 int *addr = (int *)0x10;
234
235 error = sysctl_wire_old_buffer(req, sizeof(int));
236 if (error == 0) {
237 i = 0;
238 error = sysctl_handle_int(oidp, &i, 0, req);
239 }
240 if (error != 0 || req->newptr == NULL)
241 return (error);
242 return (*addr);
243}
244
245static int
246kdb_sysctl_trap_code(SYSCTL_HANDLER_ARGS)
247{
248 int error, i;
249 void (*fp)(u_int, u_int, u_int) = (void *)0xdeadc0de;
250
251 error = sysctl_wire_old_buffer(req, sizeof(int));
252 if (error == 0) {
253 i = 0;
254 error = sysctl_handle_int(oidp, &i, 0, req);
255 }
256 if (error != 0 || req->newptr == NULL)
257 return (error);
258 (*fp)(0x11111111, 0x22222222, 0x33333333);
259 return (0);
260}
261
262static void kdb_stack_overflow(volatile int *x) __noinline;
263static void
264kdb_stack_overflow(volatile int *x)
265{
266
267 if (*x > 10000000)
268 return;
270 *x += PCPU_GET(cpuid) / 1000000;
271}
272
273static int
274kdb_sysctl_stack_overflow(SYSCTL_HANDLER_ARGS)
275{
276 int error, i;
277 volatile int x;
278
279 error = sysctl_wire_old_buffer(req, sizeof(int));
280 if (error == 0) {
281 i = 0;
282 error = sysctl_handle_int(oidp, &i, 0, req);
283 }
284 if (error != 0 || req->newptr == NULL)
285 return (error);
286 x = 0;
288 return (0);
289}
290
291void
292kdb_panic(const char *msg)
293{
294
295 printf("KDB: panic\n");
296 panic("%s", msg);
297}
298
299void
301{
302
303 printf("KDB: reboot requested\n");
304 shutdown_nice(0);
305}
306
307/*
308 * Solaris implements a new BREAK which is initiated by a character sequence
309 * CR ~ ^b which is similar to a familiar pattern used on Sun servers by the
310 * Remote Console.
311 *
312 * Note that this function may be called from almost anywhere, with interrupts
313 * disabled and with unknown locks held, so it must not access data other than
314 * its arguments. Its up to the caller to ensure that the state variable is
315 * consistent.
316 */
317#define KEY_CR 13 /* CR '\r' */
318#define KEY_TILDE 126 /* ~ */
319#define KEY_CRTLB 2 /* ^B */
320#define KEY_CRTLP 16 /* ^P */
321#define KEY_CRTLR 18 /* ^R */
322
323/* States of th KDB "alternate break sequence" detecting state machine. */
324enum {
328};
329
330int
332{
333
335 return (0);
336 kdb_enter(KDB_WHY_BREAK, "Break to debugger");
337 return (KDB_REQ_DEBUGGER);
338}
339
340static int
341kdb_alt_break_state(int key, int *state)
342{
343 int brk;
344
345 /* All states transition to KDB_ALT_BREAK_SEEN_CR on a CR. */
346 if (key == KEY_CR) {
347 *state = KDB_ALT_BREAK_SEEN_CR;
348 return (0);
349 }
350
351 brk = 0;
352 switch (*state) {
355 if (key == KEY_TILDE)
357 break;
360 if (key == KEY_CRTLB)
361 brk = KDB_REQ_DEBUGGER;
362 else if (key == KEY_CRTLP)
363 brk = KDB_REQ_PANIC;
364 else if (key == KEY_CRTLR)
365 brk = KDB_REQ_REBOOT;
366 break;
368 default:
370 break;
371 }
372 return (brk);
373}
374
375static int
376kdb_alt_break_internal(int key, int *state, int force_gdb)
377{
378 int brk;
379
381 return (0);
382 brk = kdb_alt_break_state(key, state);
383 switch (brk) {
384 case KDB_REQ_DEBUGGER:
385 if (force_gdb)
386 kdb_dbbe_select("gdb");
387 kdb_enter(KDB_WHY_BREAK, "Break to debugger");
388 break;
389
390 case KDB_REQ_PANIC:
391 if (force_gdb)
392 kdb_dbbe_select("gdb");
393 kdb_panic("Panic sequence on console");
394 break;
395
396 case KDB_REQ_REBOOT:
397 kdb_reboot();
398 break;
399 }
400 return (0);
401}
402
403int
404kdb_alt_break(int key, int *state)
405{
406
407 return (kdb_alt_break_internal(key, state, 0));
408}
409
410/*
411 * This variation on kdb_alt_break() is used only by dcons, which has its own
412 * configuration flag to force GDB use regardless of the global KDB
413 * configuration.
414 */
415int
416kdb_alt_break_gdb(int key, int *state)
417{
418
419 return (kdb_alt_break_internal(key, state, 1));
420}
421
422/*
423 * Print a backtrace of the calling thread. The backtrace is generated by
424 * the selected debugger, provided it supports backtraces. If no debugger
425 * is selected or the current debugger does not support backtraces, this
426 * function silently returns.
427 */
428void
430{
431
432 if (kdb_dbbe != NULL && kdb_dbbe->dbbe_trace != NULL) {
433 printf("KDB: stack backtrace:\n");
434 kdb_dbbe->dbbe_trace();
435 }
436#ifdef STACK
437 else {
438 struct stack st;
439
440 printf("KDB: stack backtrace:\n");
441 stack_zero(&st);
442 stack_save(&st);
444 }
445#endif
446}
447
448/*
449 * Similar to kdb_backtrace() except that it prints a backtrace of an
450 * arbitrary thread rather than the calling thread.
451 */
452void
453kdb_backtrace_thread(struct thread *td)
454{
455
456 if (kdb_dbbe != NULL && kdb_dbbe->dbbe_trace_thread != NULL) {
457 printf("KDB: stack backtrace of thread %d:\n", td->td_tid);
458 kdb_dbbe->dbbe_trace_thread(td);
459 }
460#ifdef STACK
461 else {
462 struct stack st;
463
464 printf("KDB: stack backtrace of thread %d:\n", td->td_tid);
465 if (stack_save_td(&st, td) == 0)
467 }
468#endif
469}
470
471/*
472 * Set/change the current backend.
473 */
474int
476{
477 struct kdb_dbbe *be, **iter;
478
479 SET_FOREACH(iter, kdb_dbbe_set) {
480 be = *iter;
481 if (be->dbbe_active == 0 && strcmp(be->dbbe_name, name) == 0) {
482 kdb_dbbe = be;
483 return (0);
484 }
485 }
486 return (EINVAL);
487}
488
489/*
490 * Enter the currently selected debugger. If a message has been provided,
491 * it is printed first. If the debugger does not support the enter method,
492 * it is entered by using breakpoint(), which enters the debugger through
493 * kdb_trap(). The 'why' argument will contain a more mechanically usable
494 * string than 'msg', and is relied upon by DDB scripting to identify the
495 * reason for entering the debugger so that the right script can be run.
496 */
497void
498kdb_enter(const char *why, const char *msg)
499{
500
501 if (kdb_dbbe != NULL && kdb_active == 0) {
502 if (msg != NULL)
503 printf("KDB: enter: %s\n", msg);
504 kdb_why = why;
505 breakpoint();
506 kdb_why = KDB_WHY_UNSET;
507 }
508}
509
510/*
511 * Initialize the kernel debugger interface.
512 */
513void
515{
516 struct kdb_dbbe *be, **iter;
517 int cur_pri, pri;
518
519 kdb_active = 0;
520 kdb_dbbe = NULL;
521 cur_pri = -1;
522 SET_FOREACH(iter, kdb_dbbe_set) {
523 be = *iter;
524 pri = (be->dbbe_init != NULL) ? be->dbbe_init() : -1;
525 be->dbbe_active = (pri >= 0) ? 0 : -1;
526 if (pri > cur_pri) {
527 cur_pri = pri;
528 kdb_dbbe = be;
529 }
530 }
531 if (kdb_dbbe != NULL) {
532 printf("KDB: debugger backends:");
533 SET_FOREACH(iter, kdb_dbbe_set) {
534 be = *iter;
535 if (be->dbbe_active == 0)
536 printf(" %s", be->dbbe_name);
537 }
538 printf("\n");
539 printf("KDB: current backend: %s\n",
540 kdb_dbbe->dbbe_name);
541 }
542}
543
544/*
545 * Handle contexts.
546 */
547void *
548kdb_jmpbuf(jmp_buf new)
549{
550 void *old;
551
552 old = kdb_jmpbufp;
553 kdb_jmpbufp = new;
554 return (old);
555}
556
557void
559{
560
561 if (!kdb_active || kdb_jmpbufp == NULL)
562 return;
563
564 printf("KDB: reentering\n");
566 longjmp(kdb_jmpbufp, 1);
567 /* NOTREACHED */
568}
569
570void
572{
573
574 if (!kdb_active || kdb_jmpbufp == NULL)
575 return;
576
577 longjmp(kdb_jmpbufp, 1);
578 /* NOTREACHED */
579}
580
581/*
582 * Thread-related support functions.
583 */
584struct pcb *
585kdb_thr_ctx(struct thread *thr)
586{
587#if defined(SMP) && defined(KDB_STOPPEDPCB)
588 struct pcpu *pc;
589#endif
590
591 if (thr == curthread)
592 return (&kdb_pcb);
593
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));
599 }
600#endif
601 return (thr->td_pcb);
602}
603
604struct thread *
606{
607 struct proc *p;
608 struct thread *thr;
609 u_int i;
610
611 /* This function may be called early. */
612 if (pidhashtbl == NULL)
613 return (&thread0);
614
615 for (i = 0; i <= pidhash; i++) {
616 LIST_FOREACH(p, &pidhashtbl[i], p_hash) {
617 thr = FIRST_THREAD_IN_PROC(p);
618 if (thr != NULL)
619 return (thr);
620 }
621 }
622 return (NULL);
623}
624
625struct thread *
627{
628 struct proc *p;
629
630 LIST_FOREACH(p, PIDHASH(pid), p_hash) {
631 if (p->p_pid == pid)
632 return (FIRST_THREAD_IN_PROC(p));
633 }
634 return (NULL);
635}
636
637struct thread *
638kdb_thr_lookup(lwpid_t tid)
639{
640 struct thread *thr;
641
642 thr = kdb_thr_first();
643 while (thr != NULL && thr->td_tid != tid)
644 thr = kdb_thr_next(thr);
645 return (thr);
646}
647
648struct thread *
649kdb_thr_next(struct thread *thr)
650{
651 struct proc *p;
652 u_int hash;
653
654 p = thr->td_proc;
655 thr = TAILQ_NEXT(thr, td_plist);
656 if (thr != NULL)
657 return (thr);
658 if (pidhashtbl == NULL)
659 return (NULL);
660 hash = p->p_pid & pidhash;
661 for (;;) {
662 p = LIST_NEXT(p, p_hash);
663 while (p == NULL) {
664 if (++hash > pidhash)
665 return (NULL);
666 p = LIST_FIRST(&pidhashtbl[hash]);
667 }
668 thr = FIRST_THREAD_IN_PROC(p);
669 if (thr != NULL)
670 return (thr);
671 }
672}
673
674int
675kdb_thr_select(struct thread *thr)
676{
677 if (thr == NULL)
678 return (EINVAL);
679 kdb_thread = thr;
680 kdb_thrctx = kdb_thr_ctx(thr);
681 return (0);
682}
683
684/*
685 * Enter the debugger due to a trap.
686 */
687int
688kdb_trap(int type, int code, struct trapframe *tf)
689{
690#ifdef SMP
691 cpuset_t other_cpus;
692#endif
693 struct kdb_dbbe *be;
694 register_t intr;
695 int handled;
696 int did_stop_cpus;
697
698 be = kdb_dbbe;
699 if (be == NULL || be->dbbe_trap == NULL)
700 return (0);
701
702 /* We reenter the debugger through kdb_reenter(). */
703 if (kdb_active)
704 return (0);
705
706 intr = intr_disable();
707
708 if (!SCHEDULER_STOPPED()) {
709#ifdef SMP
710 other_cpus = all_cpus;
711 CPU_ANDNOT(&other_cpus, &other_cpus, &stopped_cpus);
712 CPU_CLR(PCPU_GET(cpuid), &other_cpus);
713 stop_cpus_hard(other_cpus);
714#endif
715 curthread->td_stopsched = 1;
716 did_stop_cpus = 1;
717 } else
718 did_stop_cpus = 0;
719
720 kdb_active++;
721
722 kdb_frame = tf;
723
724 /* Let MD code do its thing first... */
725 kdb_cpu_trap(type, code);
726
727 makectx(tf, &kdb_pcb);
728 kdb_thr_select(curthread);
729
730 cngrab();
731
732 for (;;) {
733 handled = be->dbbe_trap(type, code);
734 if (be == kdb_dbbe)
735 break;
736 be = kdb_dbbe;
737 if (be == NULL || be->dbbe_trap == NULL)
738 break;
739 printf("Switching to %s back-end\n", be->dbbe_name);
740 }
741
742 cnungrab();
743
744 kdb_active--;
745
746 if (did_stop_cpus) {
747 curthread->td_stopsched = 0;
748#ifdef SMP
749 CPU_AND(&other_cpus, &other_cpus, &stopped_cpus);
750 restart_cpus(other_cpus);
751#endif
752 }
753
754 intr_restore(intr);
755
756 return (handled);
757}
device_property_type_t type
Definition: bus_if.m:941
const char * name
Definition: kern_fail.c:145
static struct bt_table st
void cngrab()
Definition: kern_cons.c:376
void cnungrab()
Definition: kern_cons.c:389
u_long pidhash
Definition: kern_proc.c:129
struct pidhashhead * pidhashtbl
Definition: kern_proc.c:127
void shutdown_nice(int howto)
void panic(const char *fmt,...)
int sysctl_wire_old_buffer(struct sysctl_req *req, size_t len)
Definition: kern_sysctl.c:2136
int sysctl_handle_int(SYSCTL_HANDLER_ARGS)
Definition: kern_sysctl.c:1644
int sysctl_handle_string(SYSCTL_HANDLER_ARGS)
Definition: kern_sysctl.c:1778
struct sbuf * sbuf_new_for_sysctl(struct sbuf *s, char *buf, int length, struct sysctl_req *req)
Definition: kern_sysctl.c:2503
uint64_t * addr
Definition: msi_if.m:89
int kdb_thr_select(struct thread *thr)
Definition: subr_kdb.c:675
@ KDB_ALT_BREAK_SEEN_NONE
Definition: subr_kdb.c:325
@ KDB_ALT_BREAK_SEEN_CR
Definition: subr_kdb.c:326
@ KDB_ALT_BREAK_SEEN_CR_TILDE
Definition: subr_kdb.c:327
static int kdb_break_to_debugger
Definition: subr_kdb.c:76
KDB_BACKEND(null, NULL, NULL, NULL, NULL)
struct thread * kdb_thr_lookup(lwpid_t tid)
Definition: subr_kdb.c:638
static int kdb_sysctl_enter(SYSCTL_HANDLER_ARGS)
Definition: subr_kdb.c:182
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)
Definition: subr_kdb.c:571
#define KDB_ALT_BREAK_TO_DEBUGGER
Definition: subr_kdb.c:73
static int kdb_sysctl_trap(SYSCTL_HANDLER_ARGS)
Definition: subr_kdb.c:230
static int kdb_sysctl_current(SYSCTL_HANDLER_ARGS)
Definition: subr_kdb.c:164
struct trapframe * kdb_frame
Definition: subr_kdb.c:62
u_char __read_frequently kdb_active
Definition: subr_kdb.c:56
void kdb_reboot(void)
Definition: subr_kdb.c:300
struct thread * kdb_thread
Definition: subr_kdb.c:61
static int kdb_alt_break_to_debugger
Definition: subr_kdb.c:77
const char *volatile kdb_why
Definition: subr_kdb.c:144
#define KDB_BREAK_TO_DEBUGGER
Definition: subr_kdb.c:67
static int kdb_sysctl_stack_overflow(SYSCTL_HANDLER_ARGS)
Definition: subr_kdb.c:274
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)
Definition: subr_kdb.c:404
void kdb_enter(const char *why, const char *msg)
Definition: subr_kdb.c:498
#define KEY_CRTLR
Definition: subr_kdb.c:321
static SYSCTL_NODE(_debug, OID_AUTO, kdb, CTLFLAG_RW|CTLFLAG_MPSAFE, NULL, "KDB nodes")
int kdb_break(void)
Definition: subr_kdb.c:331
int kdb_alt_break_gdb(int key, int *state)
Definition: subr_kdb.c:416
void kdb_reenter(void)
Definition: subr_kdb.c:558
static void * kdb_jmpbufp
Definition: subr_kdb.c:57
struct pcb * kdb_thr_ctx(struct thread *thr)
Definition: subr_kdb.c:585
void kdb_backtrace(void)
Definition: subr_kdb.c:429
static int kdb_alt_break_internal(int key, int *state, int force_gdb)
Definition: subr_kdb.c:376
void kdb_backtrace_thread(struct thread *td)
Definition: subr_kdb.c:453
#define KEY_TILDE
Definition: subr_kdb.c:318
static int kdb_sysctl_panic(SYSCTL_HANDLER_ARGS)
Definition: subr_kdb.c:200
#define KEY_CRTLB
Definition: subr_kdb.c:319
#define KEY_CRTLP
Definition: subr_kdb.c:320
void * kdb_jmpbuf(jmp_buf new)
Definition: subr_kdb.c:548
struct thread * kdb_thr_from_pid(pid_t pid)
Definition: subr_kdb.c:626
__FBSDID("$FreeBSD$")
void kdb_init(void)
Definition: subr_kdb.c:514
static int kdb_alt_break_state(int key, int *state)
Definition: subr_kdb.c:341
int kdb_trap(int type, int code, struct trapframe *tf)
Definition: subr_kdb.c:688
#define KEY_CR
Definition: subr_kdb.c:317
int kdb_dbbe_select(const char *name)
Definition: subr_kdb.c:475
static struct pcb kdb_pcb
Definition: subr_kdb.c:59
struct pcb * kdb_thrctx
Definition: subr_kdb.c:60
static int kdb_sysctl_available(SYSCTL_HANDLER_ARGS)
Definition: subr_kdb.c:147
static int kdb_sysctl_panic_str(SYSCTL_HANDLER_ARGS)
Definition: subr_kdb.c:216
struct thread * kdb_thr_next(struct thread *thr)
Definition: subr_kdb.c:649
struct thread * kdb_thr_first(void)
Definition: subr_kdb.c:605
void kdb_panic(const char *msg)
Definition: subr_kdb.c:292
static int kdb_sysctl_trap_code(SYSCTL_HANDLER_ARGS)
Definition: subr_kdb.c:246
struct kdb_dbbe * kdb_dbbe
Definition: subr_kdb.c:58
static void kdb_stack_overflow(volatile int *x) __noinline
Definition: subr_kdb.c:264
int printf(const char *fmt,...)
Definition: subr_prf.c:397
int sbuf_finish(struct sbuf *s)
Definition: subr_sbuf.c:833
void sbuf_delete(struct sbuf *s)
Definition: subr_sbuf.c:898
int sbuf_printf(struct sbuf *s, const char *fmt,...)
Definition: subr_sbuf.c:739
cpuset_t all_cpus
Definition: subr_smp.c:70
void stack_zero(struct stack *st)
Definition: subr_stack.c:89
void stack_print_ddb(const struct stack *st)
Definition: subr_stack.c:132
struct stat * buf