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

Cache object: 274128421027fc1a232f8ea61c3a6558


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