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 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 
   81 static int kdb_sysctl_available(SYSCTL_HANDLER_ARGS);
   82 static int kdb_sysctl_current(SYSCTL_HANDLER_ARGS);
   83 static int kdb_sysctl_enter(SYSCTL_HANDLER_ARGS);
   84 static int kdb_sysctl_panic(SYSCTL_HANDLER_ARGS);
   85 static int kdb_sysctl_panic_str(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 | CTLFLAG_MPSAFE, NULL,
   91     "KDB nodes");
   92 
   93 SYSCTL_PROC(_debug_kdb, OID_AUTO, available,
   94     CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, 0,
   95     kdb_sysctl_available, "A",
   96     "list of available KDB backends");
   97 
   98 SYSCTL_PROC(_debug_kdb, OID_AUTO, current,
   99     CTLTYPE_STRING | CTLFLAG_RW | CTLFLAG_MPSAFE, NULL, 0,
  100     kdb_sysctl_current, "A",
  101     "currently selected KDB backend");
  102 
  103 SYSCTL_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 
  108 SYSCTL_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 
  113 SYSCTL_PROC(_debug_kdb, OID_AUTO, panic_str,
  114     CTLTYPE_STRING | CTLFLAG_RW | CTLFLAG_SECURE | CTLFLAG_MPSAFE, NULL, 0,
  115     kdb_sysctl_panic_str, "A",
  116     "trigger a kernel panic, using the provided string as the panic message");
  117 
  118 SYSCTL_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 
  123 SYSCTL_PROC(_debug_kdb, OID_AUTO, trap_code,
  124     CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_SECURE | CTLFLAG_MPSAFE, NULL, 0,
  125     kdb_sysctl_trap_code, "I",
  126     "set to cause a page fault via code access");
  127 
  128 SYSCTL_PROC(_debug_kdb, OID_AUTO, stack_overflow,
  129     CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_SECURE | CTLFLAG_MPSAFE, NULL, 0,
  130     kdb_sysctl_stack_overflow, "I",
  131     "set to cause a stack overflow");
  132 
  133 SYSCTL_INT(_debug_kdb, OID_AUTO, break_to_debugger,
  134     CTLFLAG_RWTUN | CTLFLAG_SECURE,
  135     &kdb_break_to_debugger, 0, "Enable break to debugger");
  136 
  137 SYSCTL_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  */
  144 const char * volatile kdb_why = KDB_WHY_UNSET;
  145 
  146 static int
  147 kdb_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 
  163 static int
  164 kdb_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 
  181 static int
  182 kdb_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 
  199 static int
  200 kdb_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 
  215 static int
  216 kdb_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 
  229 static int
  230 kdb_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 
  245 static int
  246 kdb_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 
  262 static void kdb_stack_overflow(volatile int *x)  __noinline;
  263 static void
  264 kdb_stack_overflow(volatile int *x)
  265 {
  266 
  267         if (*x > 10000000)
  268                 return;
  269         kdb_stack_overflow(x);
  270         *x += PCPU_GET(cpuid) / 1000000;
  271 }
  272 
  273 static int
  274 kdb_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;
  287         kdb_stack_overflow(&x);
  288         return (0);
  289 }
  290 
  291 void
  292 kdb_panic(const char *msg)
  293 {
  294 
  295         printf("KDB: panic\n");
  296         panic("%s", msg);
  297 }
  298 
  299 void
  300 kdb_reboot(void)
  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. */
  324 enum {
  325         KDB_ALT_BREAK_SEEN_NONE,
  326         KDB_ALT_BREAK_SEEN_CR,
  327         KDB_ALT_BREAK_SEEN_CR_TILDE,
  328 };
  329 
  330 int
  331 kdb_break(void)
  332 {
  333 
  334         if (!kdb_break_to_debugger)
  335                 return (0);
  336         kdb_enter(KDB_WHY_BREAK, "Break to debugger");
  337         return (KDB_REQ_DEBUGGER);
  338 }
  339 
  340 static int
  341 kdb_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) {
  353         case KDB_ALT_BREAK_SEEN_CR:
  354                 *state = KDB_ALT_BREAK_SEEN_NONE;
  355                 if (key == KEY_TILDE)
  356                         *state = KDB_ALT_BREAK_SEEN_CR_TILDE;
  357                 break;
  358         case KDB_ALT_BREAK_SEEN_CR_TILDE:
  359                 *state = KDB_ALT_BREAK_SEEN_NONE;
  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;
  367         case KDB_ALT_BREAK_SEEN_NONE:
  368         default:
  369                 *state = KDB_ALT_BREAK_SEEN_NONE;
  370                 break;
  371         }
  372         return (brk);
  373 }
  374 
  375 static int
  376 kdb_alt_break_internal(int key, int *state, int force_gdb)
  377 {
  378         int brk;
  379 
  380         if (!kdb_alt_break_to_debugger)
  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 
  403 int
  404 kdb_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  */
  415 int
  416 kdb_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  */
  428 void
  429 kdb_backtrace(void)
  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);
  443                 stack_print_ddb(&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  */
  452 void
  453 kdb_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)
  466                         stack_print_ddb(&st);
  467         }
  468 #endif
  469 }
  470 
  471 /*
  472  * Set/change the current backend.
  473  */
  474 int
  475 kdb_dbbe_select(const char *name)
  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  */
  497 void
  498 kdb_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  */
  513 void
  514 kdb_init(void)
  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  */
  547 void *
  548 kdb_jmpbuf(jmp_buf new)
  549 {
  550         void *old;
  551 
  552         old = kdb_jmpbufp;
  553         kdb_jmpbufp = new;
  554         return (old);
  555 }
  556 
  557 void
  558 kdb_reenter(void)
  559 {
  560 
  561         if (!kdb_active || kdb_jmpbufp == NULL)
  562                 return;
  563 
  564         printf("KDB: reentering\n");
  565         kdb_backtrace();
  566         longjmp(kdb_jmpbufp, 1);
  567         /* NOTREACHED */
  568 }
  569 
  570 void
  571 kdb_reenter_silent(void)
  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  */
  584 struct pcb *
  585 kdb_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 
  604 struct thread *
  605 kdb_thr_first(void)
  606 {
  607         struct proc *p;
  608         struct thread *thr;
  609         u_int i;
  610 
  611         for (i = 0; i <= pidhash; i++) {
  612                 LIST_FOREACH(p, &pidhashtbl[i], p_hash) {
  613                         thr = FIRST_THREAD_IN_PROC(p);
  614                         if (thr != NULL)
  615                                 return (thr);
  616                 }
  617         }
  618         return (NULL);
  619 }
  620 
  621 struct thread *
  622 kdb_thr_from_pid(pid_t pid)
  623 {
  624         struct proc *p;
  625 
  626         LIST_FOREACH(p, PIDHASH(pid), p_hash) {
  627                 if (p->p_pid == pid)
  628                         return (FIRST_THREAD_IN_PROC(p));
  629         }
  630         return (NULL);
  631 }
  632 
  633 struct thread *
  634 kdb_thr_lookup(lwpid_t tid)
  635 {
  636         struct thread *thr;
  637 
  638         thr = kdb_thr_first();
  639         while (thr != NULL && thr->td_tid != tid)
  640                 thr = kdb_thr_next(thr);
  641         return (thr);
  642 }
  643 
  644 struct thread *
  645 kdb_thr_next(struct thread *thr)
  646 {
  647         struct proc *p;
  648         u_int hash;
  649 
  650         p = thr->td_proc;
  651         thr = TAILQ_NEXT(thr, td_plist);
  652         if (thr != NULL)
  653                 return (thr);
  654         hash = p->p_pid & pidhash;
  655         for (;;) {
  656                 p = LIST_NEXT(p, p_hash);
  657                 while (p == NULL) {
  658                         if (++hash > pidhash)
  659                                 return (NULL);
  660                         p = LIST_FIRST(&pidhashtbl[hash]);
  661                 }
  662                 thr = FIRST_THREAD_IN_PROC(p);
  663                 if (thr != NULL)
  664                         return (thr);
  665         }
  666 }
  667 
  668 int
  669 kdb_thr_select(struct thread *thr)
  670 {
  671         if (thr == NULL)
  672                 return (EINVAL);
  673         kdb_thread = thr;
  674         kdb_thrctx = kdb_thr_ctx(thr);
  675         return (0);
  676 }
  677 
  678 /*
  679  * Enter the debugger due to a trap.
  680  */
  681 int
  682 kdb_trap(int type, int code, struct trapframe *tf)
  683 {
  684 #ifdef SMP
  685         cpuset_t other_cpus;
  686 #endif
  687         struct kdb_dbbe *be;
  688         register_t intr;
  689         int handled;
  690         int did_stop_cpus;
  691 
  692         be = kdb_dbbe;
  693         if (be == NULL || be->dbbe_trap == NULL)
  694                 return (0);
  695 
  696         /* We reenter the debugger through kdb_reenter(). */
  697         if (kdb_active)
  698                 return (0);
  699 
  700         intr = intr_disable();
  701 
  702         if (!SCHEDULER_STOPPED()) {
  703 #ifdef SMP
  704                 other_cpus = all_cpus;
  705                 CPU_ANDNOT(&other_cpus, &stopped_cpus);
  706                 CPU_CLR(PCPU_GET(cpuid), &other_cpus);
  707                 stop_cpus_hard(other_cpus);
  708 #endif
  709                 curthread->td_stopsched = 1;
  710                 did_stop_cpus = 1;
  711         } else
  712                 did_stop_cpus = 0;
  713 
  714         kdb_active++;
  715 
  716         kdb_frame = tf;
  717 
  718         /* Let MD code do its thing first... */
  719         kdb_cpu_trap(type, code);
  720 
  721         makectx(tf, &kdb_pcb);
  722         kdb_thr_select(curthread);
  723 
  724         cngrab();
  725 
  726         for (;;) {
  727                 handled = be->dbbe_trap(type, code);
  728                 if (be == kdb_dbbe)
  729                         break;
  730                 be = kdb_dbbe;
  731                 if (be == NULL || be->dbbe_trap == NULL)
  732                         break;
  733                 printf("Switching to %s back-end\n", be->dbbe_name);
  734         }
  735 
  736         cnungrab();
  737 
  738         kdb_active--;
  739 
  740         if (did_stop_cpus) {
  741                 curthread->td_stopsched = 0;
  742 #ifdef SMP
  743                 CPU_AND(&other_cpus, &stopped_cpus);
  744                 restart_cpus(other_cpus);
  745 #endif
  746         }
  747 
  748         intr_restore(intr);
  749 
  750         return (handled);
  751 }

Cache object: 569553deabfb4d93c4b412b6b5beb045


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