The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/kern/subr_kdb.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    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: releng/12.0/sys/kern/subr_kdb.c 335441 2018-06-20 11:42:06Z bz $");
   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 
   56 u_char __read_frequently kdb_active = 0;
   57 static void *kdb_jmpbufp = NULL;
   58 struct kdb_dbbe *kdb_dbbe = NULL;
   59 static struct pcb kdb_pcb;
   60 struct pcb *kdb_thrctx = NULL;
   61 struct thread *kdb_thread = NULL;
   62 struct 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 
   76 static int      kdb_break_to_debugger = KDB_BREAK_TO_DEBUGGER;
   77 static int      kdb_alt_break_to_debugger = KDB_ALT_BREAK_TO_DEBUGGER;
   78 
   79 KDB_BACKEND(null, NULL, NULL, NULL, NULL);
   80 SET_DECLARE(kdb_dbbe_set, struct kdb_dbbe);
   81 
   82 static int kdb_sysctl_available(SYSCTL_HANDLER_ARGS);
   83 static int kdb_sysctl_current(SYSCTL_HANDLER_ARGS);
   84 static int kdb_sysctl_enter(SYSCTL_HANDLER_ARGS);
   85 static int kdb_sysctl_panic(SYSCTL_HANDLER_ARGS);
   86 static int kdb_sysctl_trap(SYSCTL_HANDLER_ARGS);
   87 static int kdb_sysctl_trap_code(SYSCTL_HANDLER_ARGS);
   88 static int kdb_sysctl_stack_overflow(SYSCTL_HANDLER_ARGS);
   89 
   90 static SYSCTL_NODE(_debug, OID_AUTO, kdb, CTLFLAG_RW, NULL, "KDB nodes");
   91 
   92 SYSCTL_PROC(_debug_kdb, OID_AUTO, available, CTLTYPE_STRING | CTLFLAG_RD, NULL,
   93     0, kdb_sysctl_available, "A", "list of available KDB backends");
   94 
   95 SYSCTL_PROC(_debug_kdb, OID_AUTO, current, CTLTYPE_STRING | CTLFLAG_RW, NULL,
   96     0, kdb_sysctl_current, "A", "currently selected KDB backend");
   97 
   98 SYSCTL_PROC(_debug_kdb, OID_AUTO, enter,
   99     CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_SECURE, NULL, 0,
  100     kdb_sysctl_enter, "I", "set to enter the debugger");
  101 
  102 SYSCTL_PROC(_debug_kdb, OID_AUTO, panic,
  103     CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_SECURE, NULL, 0,
  104     kdb_sysctl_panic, "I", "set to panic the kernel");
  105 
  106 SYSCTL_PROC(_debug_kdb, OID_AUTO, trap,
  107     CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_SECURE, NULL, 0,
  108     kdb_sysctl_trap, "I", "set to cause a page fault via data access");
  109 
  110 SYSCTL_PROC(_debug_kdb, OID_AUTO, trap_code,
  111     CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_SECURE, NULL, 0,
  112     kdb_sysctl_trap_code, "I", "set to cause a page fault via code access");
  113 
  114 SYSCTL_PROC(_debug_kdb, OID_AUTO, stack_overflow,
  115     CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_SECURE, NULL, 0,
  116     kdb_sysctl_stack_overflow, "I", "set to cause a stack overflow");
  117 
  118 SYSCTL_INT(_debug_kdb, OID_AUTO, break_to_debugger,
  119     CTLFLAG_RWTUN | CTLFLAG_SECURE,
  120     &kdb_break_to_debugger, 0, "Enable break to debugger");
  121 
  122 SYSCTL_INT(_debug_kdb, OID_AUTO, alt_break_to_debugger,
  123     CTLFLAG_RWTUN | CTLFLAG_SECURE,
  124     &kdb_alt_break_to_debugger, 0, "Enable alternative break to debugger");
  125 
  126 /*
  127  * Flag to indicate to debuggers why the debugger was entered.
  128  */
  129 const char * volatile kdb_why = KDB_WHY_UNSET;
  130 
  131 static int
  132 kdb_sysctl_available(SYSCTL_HANDLER_ARGS)
  133 {
  134         struct kdb_dbbe **iter;
  135         struct sbuf sbuf;
  136         int error;
  137 
  138         sbuf_new_for_sysctl(&sbuf, NULL, 64, req);
  139         SET_FOREACH(iter, kdb_dbbe_set) {
  140                 if ((*iter)->dbbe_active == 0)
  141                         sbuf_printf(&sbuf, "%s ", (*iter)->dbbe_name);
  142         }
  143         error = sbuf_finish(&sbuf);
  144         sbuf_delete(&sbuf);
  145         return (error);
  146 }
  147 
  148 static int
  149 kdb_sysctl_current(SYSCTL_HANDLER_ARGS)
  150 {
  151         char buf[16];
  152         int error;
  153 
  154         if (kdb_dbbe != NULL)
  155                 strlcpy(buf, kdb_dbbe->dbbe_name, sizeof(buf));
  156         else
  157                 *buf = '\0';
  158         error = sysctl_handle_string(oidp, buf, sizeof(buf), req);
  159         if (error != 0 || req->newptr == NULL)
  160                 return (error);
  161         if (kdb_active)
  162                 return (EBUSY);
  163         return (kdb_dbbe_select(buf));
  164 }
  165 
  166 static int
  167 kdb_sysctl_enter(SYSCTL_HANDLER_ARGS)
  168 {
  169         int error, i;
  170 
  171         error = sysctl_wire_old_buffer(req, sizeof(int));
  172         if (error == 0) {
  173                 i = 0;
  174                 error = sysctl_handle_int(oidp, &i, 0, req);
  175         }
  176         if (error != 0 || req->newptr == NULL)
  177                 return (error);
  178         if (kdb_active)
  179                 return (EBUSY);
  180         kdb_enter(KDB_WHY_SYSCTL, "sysctl debug.kdb.enter");
  181         return (0);
  182 }
  183 
  184 static int
  185 kdb_sysctl_panic(SYSCTL_HANDLER_ARGS)
  186 {
  187         int error, i;
  188 
  189         error = sysctl_wire_old_buffer(req, sizeof(int));
  190         if (error == 0) {
  191                 i = 0;
  192                 error = sysctl_handle_int(oidp, &i, 0, req);
  193         }
  194         if (error != 0 || req->newptr == NULL)
  195                 return (error);
  196         panic("kdb_sysctl_panic");
  197         return (0);
  198 }
  199 
  200 static int
  201 kdb_sysctl_trap(SYSCTL_HANDLER_ARGS)
  202 {
  203         int error, i;
  204         int *addr = (int *)0x10;
  205 
  206         error = sysctl_wire_old_buffer(req, sizeof(int));
  207         if (error == 0) {
  208                 i = 0;
  209                 error = sysctl_handle_int(oidp, &i, 0, req);
  210         }
  211         if (error != 0 || req->newptr == NULL)
  212                 return (error);
  213         return (*addr);
  214 }
  215 
  216 static int
  217 kdb_sysctl_trap_code(SYSCTL_HANDLER_ARGS)
  218 {
  219         int error, i;
  220         void (*fp)(u_int, u_int, u_int) = (void *)0xdeadc0de;
  221 
  222         error = sysctl_wire_old_buffer(req, sizeof(int));
  223         if (error == 0) {
  224                 i = 0;
  225                 error = sysctl_handle_int(oidp, &i, 0, req);
  226         }
  227         if (error != 0 || req->newptr == NULL)
  228                 return (error);
  229         (*fp)(0x11111111, 0x22222222, 0x33333333);
  230         return (0);
  231 }
  232 
  233 static void kdb_stack_overflow(volatile int *x)  __noinline;
  234 static void
  235 kdb_stack_overflow(volatile int *x)
  236 {
  237 
  238         if (*x > 10000000)
  239                 return;
  240         kdb_stack_overflow(x);
  241         *x += PCPU_GET(cpuid) / 1000000;
  242 }
  243 
  244 static int
  245 kdb_sysctl_stack_overflow(SYSCTL_HANDLER_ARGS)
  246 {
  247         int error, i;
  248         volatile int x;
  249 
  250         error = sysctl_wire_old_buffer(req, sizeof(int));
  251         if (error == 0) {
  252                 i = 0;
  253                 error = sysctl_handle_int(oidp, &i, 0, req);
  254         }
  255         if (error != 0 || req->newptr == NULL)
  256                 return (error);
  257         x = 0;
  258         kdb_stack_overflow(&x);
  259         return (0);
  260 }
  261 
  262 
  263 void
  264 kdb_panic(const char *msg)
  265 {
  266 
  267         printf("KDB: panic\n");
  268         panic("%s", msg);
  269 }
  270 
  271 void
  272 kdb_reboot(void)
  273 {
  274 
  275         printf("KDB: reboot requested\n");
  276         shutdown_nice(0);
  277 }
  278 
  279 /*
  280  * Solaris implements a new BREAK which is initiated by a character sequence
  281  * CR ~ ^b which is similar to a familiar pattern used on Sun servers by the
  282  * Remote Console.
  283  *
  284  * Note that this function may be called from almost anywhere, with interrupts
  285  * disabled and with unknown locks held, so it must not access data other than
  286  * its arguments.  Its up to the caller to ensure that the state variable is
  287  * consistent.
  288  */
  289 #define KEY_CR          13      /* CR '\r' */
  290 #define KEY_TILDE       126     /* ~ */
  291 #define KEY_CRTLB       2       /* ^B */
  292 #define KEY_CRTLP       16      /* ^P */
  293 #define KEY_CRTLR       18      /* ^R */
  294 
  295 /* States of th KDB "alternate break sequence" detecting state machine. */
  296 enum {
  297         KDB_ALT_BREAK_SEEN_NONE,
  298         KDB_ALT_BREAK_SEEN_CR,
  299         KDB_ALT_BREAK_SEEN_CR_TILDE,
  300 };
  301 
  302 int
  303 kdb_break(void)
  304 {
  305 
  306         if (!kdb_break_to_debugger)
  307                 return (0);
  308         kdb_enter(KDB_WHY_BREAK, "Break to debugger");
  309         return (KDB_REQ_DEBUGGER);
  310 }
  311 
  312 static int
  313 kdb_alt_break_state(int key, int *state)
  314 {
  315         int brk;
  316 
  317         /* All states transition to KDB_ALT_BREAK_SEEN_CR on a CR. */
  318         if (key == KEY_CR) {
  319                 *state = KDB_ALT_BREAK_SEEN_CR;
  320                 return (0);
  321         }
  322 
  323         brk = 0;
  324         switch (*state) {
  325         case KDB_ALT_BREAK_SEEN_CR:
  326                 *state = KDB_ALT_BREAK_SEEN_NONE;
  327                 if (key == KEY_TILDE)
  328                         *state = KDB_ALT_BREAK_SEEN_CR_TILDE;
  329                 break;
  330         case KDB_ALT_BREAK_SEEN_CR_TILDE:
  331                 *state = KDB_ALT_BREAK_SEEN_NONE;
  332                 if (key == KEY_CRTLB)
  333                         brk = KDB_REQ_DEBUGGER;
  334                 else if (key == KEY_CRTLP)
  335                         brk = KDB_REQ_PANIC;
  336                 else if (key == KEY_CRTLR)
  337                         brk = KDB_REQ_REBOOT;
  338                 break;
  339         case KDB_ALT_BREAK_SEEN_NONE:
  340         default:
  341                 *state = KDB_ALT_BREAK_SEEN_NONE;
  342                 break;
  343         }
  344         return (brk);
  345 }
  346 
  347 static int
  348 kdb_alt_break_internal(int key, int *state, int force_gdb)
  349 {
  350         int brk;
  351 
  352         if (!kdb_alt_break_to_debugger)
  353                 return (0);
  354         brk = kdb_alt_break_state(key, state);
  355         switch (brk) {
  356         case KDB_REQ_DEBUGGER:
  357                 if (force_gdb)
  358                         kdb_dbbe_select("gdb");
  359                 kdb_enter(KDB_WHY_BREAK, "Break to debugger");
  360                 break;
  361 
  362         case KDB_REQ_PANIC:
  363                 if (force_gdb)
  364                         kdb_dbbe_select("gdb");
  365                 kdb_panic("Panic sequence on console");
  366                 break;
  367 
  368         case KDB_REQ_REBOOT:
  369                 kdb_reboot();
  370                 break;
  371         }
  372         return (0);
  373 }
  374 
  375 int
  376 kdb_alt_break(int key, int *state)
  377 {
  378 
  379         return (kdb_alt_break_internal(key, state, 0));
  380 }
  381 
  382 /*
  383  * This variation on kdb_alt_break() is used only by dcons, which has its own
  384  * configuration flag to force GDB use regardless of the global KDB
  385  * configuration.
  386  */
  387 int
  388 kdb_alt_break_gdb(int key, int *state)
  389 {
  390 
  391         return (kdb_alt_break_internal(key, state, 1));
  392 }
  393 
  394 /*
  395  * Print a backtrace of the calling thread. The backtrace is generated by
  396  * the selected debugger, provided it supports backtraces. If no debugger
  397  * is selected or the current debugger does not support backtraces, this
  398  * function silently returns.
  399  */
  400 void
  401 kdb_backtrace(void)
  402 {
  403 
  404         if (kdb_dbbe != NULL && kdb_dbbe->dbbe_trace != NULL) {
  405                 printf("KDB: stack backtrace:\n");
  406                 kdb_dbbe->dbbe_trace();
  407         }
  408 #ifdef STACK
  409         else {
  410                 struct stack st;
  411 
  412                 printf("KDB: stack backtrace:\n");
  413                 stack_zero(&st);
  414                 stack_save(&st);
  415                 stack_print_ddb(&st);
  416         }
  417 #endif
  418 }
  419 
  420 /*
  421  * Similar to kdb_backtrace() except that it prints a backtrace of an
  422  * arbitrary thread rather than the calling thread.
  423  */
  424 void
  425 kdb_backtrace_thread(struct thread *td)
  426 {
  427 
  428         if (kdb_dbbe != NULL && kdb_dbbe->dbbe_trace_thread != NULL) {
  429                 printf("KDB: stack backtrace of thread %d:\n", td->td_tid);
  430                 kdb_dbbe->dbbe_trace_thread(td);
  431         }
  432 #ifdef STACK
  433         else {
  434                 struct stack st;
  435 
  436                 printf("KDB: stack backtrace of thread %d:\n", td->td_tid);
  437                 stack_zero(&st);
  438                 stack_save_td(&st, td);
  439                 stack_print_ddb(&st);
  440         }
  441 #endif
  442 }
  443 
  444 /*
  445  * Set/change the current backend.
  446  */
  447 int
  448 kdb_dbbe_select(const char *name)
  449 {
  450         struct kdb_dbbe *be, **iter;
  451 
  452         SET_FOREACH(iter, kdb_dbbe_set) {
  453                 be = *iter;
  454                 if (be->dbbe_active == 0 && strcmp(be->dbbe_name, name) == 0) {
  455                         kdb_dbbe = be;
  456                         return (0);
  457                 }
  458         }
  459         return (EINVAL);
  460 }
  461 
  462 /*
  463  * Enter the currently selected debugger. If a message has been provided,
  464  * it is printed first. If the debugger does not support the enter method,
  465  * it is entered by using breakpoint(), which enters the debugger through
  466  * kdb_trap().  The 'why' argument will contain a more mechanically usable
  467  * string than 'msg', and is relied upon by DDB scripting to identify the
  468  * reason for entering the debugger so that the right script can be run.
  469  */
  470 void
  471 kdb_enter(const char *why, const char *msg)
  472 {
  473 
  474         if (kdb_dbbe != NULL && kdb_active == 0) {
  475                 if (msg != NULL)
  476                         printf("KDB: enter: %s\n", msg);
  477                 kdb_why = why;
  478                 breakpoint();
  479                 kdb_why = KDB_WHY_UNSET;
  480         }
  481 }
  482 
  483 /*
  484  * Initialize the kernel debugger interface.
  485  */
  486 void
  487 kdb_init(void)
  488 {
  489         struct kdb_dbbe *be, **iter;
  490         int cur_pri, pri;
  491 
  492         kdb_active = 0;
  493         kdb_dbbe = NULL;
  494         cur_pri = -1;
  495         SET_FOREACH(iter, kdb_dbbe_set) {
  496                 be = *iter;
  497                 pri = (be->dbbe_init != NULL) ? be->dbbe_init() : -1;
  498                 be->dbbe_active = (pri >= 0) ? 0 : -1;
  499                 if (pri > cur_pri) {
  500                         cur_pri = pri;
  501                         kdb_dbbe = be;
  502                 }
  503         }
  504         if (kdb_dbbe != NULL) {
  505                 printf("KDB: debugger backends:");
  506                 SET_FOREACH(iter, kdb_dbbe_set) {
  507                         be = *iter;
  508                         if (be->dbbe_active == 0)
  509                                 printf(" %s", be->dbbe_name);
  510                 }
  511                 printf("\n");
  512                 printf("KDB: current backend: %s\n",
  513                     kdb_dbbe->dbbe_name);
  514         }
  515 }
  516 
  517 /*
  518  * Handle contexts.
  519  */
  520 void *
  521 kdb_jmpbuf(jmp_buf new)
  522 {
  523         void *old;
  524 
  525         old = kdb_jmpbufp;
  526         kdb_jmpbufp = new;
  527         return (old);
  528 }
  529 
  530 void
  531 kdb_reenter(void)
  532 {
  533 
  534         if (!kdb_active || kdb_jmpbufp == NULL)
  535                 return;
  536 
  537         printf("KDB: reentering\n");
  538         kdb_backtrace();
  539         longjmp(kdb_jmpbufp, 1);
  540         /* NOTREACHED */
  541 }
  542 
  543 void
  544 kdb_reenter_silent(void)
  545 {
  546 
  547         if (!kdb_active || kdb_jmpbufp == NULL)
  548                 return;
  549 
  550         longjmp(kdb_jmpbufp, 1);
  551         /* NOTREACHED */
  552 }
  553 
  554 /*
  555  * Thread-related support functions.
  556  */
  557 struct pcb *
  558 kdb_thr_ctx(struct thread *thr)
  559 {
  560 #if defined(SMP) && defined(KDB_STOPPEDPCB)
  561         struct pcpu *pc;
  562 #endif
  563 
  564         if (thr == curthread)
  565                 return (&kdb_pcb);
  566 
  567 #if defined(SMP) && defined(KDB_STOPPEDPCB)
  568         STAILQ_FOREACH(pc, &cpuhead, pc_allcpu)  {
  569                 if (pc->pc_curthread == thr &&
  570                     CPU_ISSET(pc->pc_cpuid, &stopped_cpus))
  571                         return (KDB_STOPPEDPCB(pc));
  572         }
  573 #endif
  574         return (thr->td_pcb);
  575 }
  576 
  577 struct thread *
  578 kdb_thr_first(void)
  579 {
  580         struct proc *p;
  581         struct thread *thr;
  582 
  583         FOREACH_PROC_IN_SYSTEM(p) {
  584                 if (p->p_flag & P_INMEM) {
  585                         thr = FIRST_THREAD_IN_PROC(p);
  586                         if (thr != NULL)
  587                                 return (thr);
  588                 }
  589         }
  590         return (NULL);
  591 }
  592 
  593 struct thread *
  594 kdb_thr_from_pid(pid_t pid)
  595 {
  596         struct proc *p;
  597 
  598         FOREACH_PROC_IN_SYSTEM(p) {
  599                 if (p->p_flag & P_INMEM && p->p_pid == pid)
  600                         return (FIRST_THREAD_IN_PROC(p));
  601         }
  602         return (NULL);
  603 }
  604 
  605 struct thread *
  606 kdb_thr_lookup(lwpid_t tid)
  607 {
  608         struct thread *thr;
  609 
  610         thr = kdb_thr_first();
  611         while (thr != NULL && thr->td_tid != tid)
  612                 thr = kdb_thr_next(thr);
  613         return (thr);
  614 }
  615 
  616 struct thread *
  617 kdb_thr_next(struct thread *thr)
  618 {
  619         struct proc *p;
  620 
  621         p = thr->td_proc;
  622         thr = TAILQ_NEXT(thr, td_plist);
  623         do {
  624                 if (thr != NULL)
  625                         return (thr);
  626                 p = LIST_NEXT(p, p_list);
  627                 if (p != NULL && (p->p_flag & P_INMEM))
  628                         thr = FIRST_THREAD_IN_PROC(p);
  629         } while (p != NULL);
  630         return (NULL);
  631 }
  632 
  633 int
  634 kdb_thr_select(struct thread *thr)
  635 {
  636         if (thr == NULL)
  637                 return (EINVAL);
  638         kdb_thread = thr;
  639         kdb_thrctx = kdb_thr_ctx(thr);
  640         return (0);
  641 }
  642 
  643 /*
  644  * Enter the debugger due to a trap.
  645  */
  646 int
  647 kdb_trap(int type, int code, struct trapframe *tf)
  648 {
  649 #ifdef SMP
  650         cpuset_t other_cpus;
  651 #endif
  652         struct kdb_dbbe *be;
  653         register_t intr;
  654         int handled;
  655 #ifdef SMP
  656         int did_stop_cpus;
  657 #endif
  658 
  659         be = kdb_dbbe;
  660         if (be == NULL || be->dbbe_trap == NULL)
  661                 return (0);
  662 
  663         /* We reenter the debugger through kdb_reenter(). */
  664         if (kdb_active)
  665                 return (0);
  666 
  667         intr = intr_disable();
  668 
  669 #ifdef SMP
  670         if (!SCHEDULER_STOPPED()) {
  671                 other_cpus = all_cpus;
  672                 CPU_NAND(&other_cpus, &stopped_cpus);
  673                 CPU_CLR(PCPU_GET(cpuid), &other_cpus);
  674                 stop_cpus_hard(other_cpus);
  675                 did_stop_cpus = 1;
  676         } else
  677                 did_stop_cpus = 0;
  678 #endif
  679 
  680         kdb_active++;
  681 
  682         kdb_frame = tf;
  683 
  684         /* Let MD code do its thing first... */
  685         kdb_cpu_trap(type, code);
  686 
  687         makectx(tf, &kdb_pcb);
  688         kdb_thr_select(curthread);
  689 
  690         cngrab();
  691 
  692         for (;;) {
  693                 handled = be->dbbe_trap(type, code);
  694                 if (be == kdb_dbbe)
  695                         break;
  696                 be = kdb_dbbe;
  697                 if (be == NULL || be->dbbe_trap == NULL)
  698                         break;
  699                 printf("Switching to %s back-end\n", be->dbbe_name);
  700         }
  701 
  702         cnungrab();
  703 
  704         kdb_active--;
  705 
  706 #ifdef SMP
  707         if (did_stop_cpus) {
  708                 CPU_AND(&other_cpus, &stopped_cpus);
  709                 restart_cpus(other_cpus);
  710         }
  711 #endif
  712 
  713         intr_restore(intr);
  714 
  715         return (handled);
  716 }

Cache object: c27a814b0c9c98de663ee60c5193a3ea


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.