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

Cache object: d09ba59940a6075997f3acd401eb657d


[ 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.