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/8.1/sys/kern/subr_kdb.c 199583 2009-11-20 15:27:52Z jhb $");
   29 
   30 #include "opt_kdb.h"
   31 
   32 #include <sys/param.h>
   33 #include <sys/systm.h>
   34 #include <sys/kdb.h>
   35 #include <sys/kernel.h>
   36 #include <sys/malloc.h>
   37 #include <sys/pcpu.h>
   38 #include <sys/proc.h>
   39 #include <sys/smp.h>
   40 #include <sys/sysctl.h>
   41 
   42 #include <machine/kdb.h>
   43 #include <machine/pcb.h>
   44 
   45 #ifdef SMP
   46 #include <machine/smp.h>
   47 #endif
   48 
   49 int kdb_active = 0;
   50 static void *kdb_jmpbufp = NULL;
   51 struct kdb_dbbe *kdb_dbbe = NULL;
   52 static struct pcb kdb_pcb;
   53 struct pcb *kdb_thrctx = NULL;
   54 struct thread *kdb_thread = NULL;
   55 struct trapframe *kdb_frame = NULL;
   56 
   57 KDB_BACKEND(null, NULL, NULL, NULL);
   58 SET_DECLARE(kdb_dbbe_set, struct kdb_dbbe);
   59 
   60 static int kdb_sysctl_available(SYSCTL_HANDLER_ARGS);
   61 static int kdb_sysctl_current(SYSCTL_HANDLER_ARGS);
   62 static int kdb_sysctl_enter(SYSCTL_HANDLER_ARGS);
   63 static int kdb_sysctl_panic(SYSCTL_HANDLER_ARGS);
   64 static int kdb_sysctl_trap(SYSCTL_HANDLER_ARGS);
   65 static int kdb_sysctl_trap_code(SYSCTL_HANDLER_ARGS);
   66 
   67 SYSCTL_NODE(_debug, OID_AUTO, kdb, CTLFLAG_RW, NULL, "KDB nodes");
   68 
   69 SYSCTL_PROC(_debug_kdb, OID_AUTO, available, CTLTYPE_STRING | CTLFLAG_RD, NULL,
   70     0, kdb_sysctl_available, "A", "list of available KDB backends");
   71 
   72 SYSCTL_PROC(_debug_kdb, OID_AUTO, current, CTLTYPE_STRING | CTLFLAG_RW, NULL,
   73     0, kdb_sysctl_current, "A", "currently selected KDB backend");
   74 
   75 SYSCTL_PROC(_debug_kdb, OID_AUTO, enter, CTLTYPE_INT | CTLFLAG_RW, NULL, 0,
   76     kdb_sysctl_enter, "I", "set to enter the debugger");
   77 
   78 SYSCTL_PROC(_debug_kdb, OID_AUTO, panic, CTLTYPE_INT | CTLFLAG_RW, NULL, 0,
   79     kdb_sysctl_panic, "I", "set to panic the kernel");
   80 
   81 SYSCTL_PROC(_debug_kdb, OID_AUTO, trap, CTLTYPE_INT | CTLFLAG_RW, NULL, 0,
   82     kdb_sysctl_trap, "I", "set to cause a page fault via data access");
   83 
   84 SYSCTL_PROC(_debug_kdb, OID_AUTO, trap_code, CTLTYPE_INT | CTLFLAG_RW, NULL, 0,
   85     kdb_sysctl_trap_code, "I", "set to cause a page fault via code access");
   86 
   87 /*
   88  * Flag indicating whether or not to IPI the other CPUs to stop them on
   89  * entering the debugger.  Sometimes, this will result in a deadlock as
   90  * stop_cpus() waits for the other cpus to stop, so we allow it to be
   91  * disabled.  In order to maximize the chances of success, use a hard
   92  * stop for that.
   93  */
   94 #ifdef SMP
   95 static int kdb_stop_cpus = 1;
   96 SYSCTL_INT(_debug_kdb, OID_AUTO, stop_cpus, CTLTYPE_INT | CTLFLAG_RW,
   97     &kdb_stop_cpus, 0, "stop other CPUs when entering the debugger");
   98 TUNABLE_INT("debug.kdb.stop_cpus", &kdb_stop_cpus);
   99 #endif
  100 
  101 /*
  102  * Flag to indicate to debuggers why the debugger was entered.
  103  */
  104 const char * volatile kdb_why = KDB_WHY_UNSET;
  105 
  106 static int
  107 kdb_sysctl_available(SYSCTL_HANDLER_ARGS)
  108 {
  109         struct kdb_dbbe *be, **iter;
  110         char *avail, *p;
  111         ssize_t len, sz;
  112         int error;
  113 
  114         sz = 0;
  115         SET_FOREACH(iter, kdb_dbbe_set) {
  116                 be = *iter;
  117                 if (be->dbbe_active == 0)
  118                         sz += strlen(be->dbbe_name) + 1;
  119         }
  120         sz++;
  121         avail = malloc(sz, M_TEMP, M_WAITOK);
  122         p = avail;
  123         *p = '\0';
  124 
  125         SET_FOREACH(iter, kdb_dbbe_set) {
  126                 be = *iter;
  127                 if (be->dbbe_active == 0) {
  128                         len = snprintf(p, sz, "%s ", be->dbbe_name);
  129                         p += len;
  130                         sz -= len;
  131                 }
  132         }
  133         KASSERT(sz >= 0, ("%s", __func__));
  134         error = sysctl_handle_string(oidp, avail, 0, req);
  135         free(avail, M_TEMP);
  136         return (error);
  137 }
  138 
  139 static int
  140 kdb_sysctl_current(SYSCTL_HANDLER_ARGS)
  141 {
  142         char buf[16];
  143         int error;
  144 
  145         if (kdb_dbbe != NULL) {
  146                 strncpy(buf, kdb_dbbe->dbbe_name, sizeof(buf));
  147                 buf[sizeof(buf) - 1] = '\0';
  148         } else
  149                 *buf = '\0';
  150         error = sysctl_handle_string(oidp, buf, sizeof(buf), req);
  151         if (error != 0 || req->newptr == NULL)
  152                 return (error);
  153         if (kdb_active)
  154                 return (EBUSY);
  155         return (kdb_dbbe_select(buf));
  156 }
  157 
  158 static int
  159 kdb_sysctl_enter(SYSCTL_HANDLER_ARGS)
  160 {
  161         int error, i;
  162 
  163         error = sysctl_wire_old_buffer(req, sizeof(int));
  164         if (error == 0) {
  165                 i = 0;
  166                 error = sysctl_handle_int(oidp, &i, 0, req);
  167         }
  168         if (error != 0 || req->newptr == NULL)
  169                 return (error);
  170         if (kdb_active)
  171                 return (EBUSY);
  172         kdb_enter(KDB_WHY_SYSCTL, "sysctl debug.kdb.enter");
  173         return (0);
  174 }
  175 
  176 static int
  177 kdb_sysctl_panic(SYSCTL_HANDLER_ARGS)
  178 {
  179         int error, i;
  180 
  181         error = sysctl_wire_old_buffer(req, sizeof(int));
  182         if (error == 0) {
  183                 i = 0;
  184                 error = sysctl_handle_int(oidp, &i, 0, req);
  185         }
  186         if (error != 0 || req->newptr == NULL)
  187                 return (error);
  188         panic("kdb_sysctl_panic");
  189         return (0);
  190 }
  191 
  192 static int
  193 kdb_sysctl_trap(SYSCTL_HANDLER_ARGS)
  194 {
  195         int error, i;
  196         int *addr = (int *)0x10;
  197 
  198         error = sysctl_wire_old_buffer(req, sizeof(int));
  199         if (error == 0) {
  200                 i = 0;
  201                 error = sysctl_handle_int(oidp, &i, 0, req);
  202         }
  203         if (error != 0 || req->newptr == NULL)
  204                 return (error);
  205         return (*addr);
  206 }
  207 
  208 static int
  209 kdb_sysctl_trap_code(SYSCTL_HANDLER_ARGS)
  210 {
  211         int error, i;
  212         void (*fp)(u_int, u_int, u_int) = (void *)0xdeadc0de;
  213 
  214         error = sysctl_wire_old_buffer(req, sizeof(int));
  215         if (error == 0) {
  216                 i = 0;
  217                 error = sysctl_handle_int(oidp, &i, 0, req);
  218         }
  219         if (error != 0 || req->newptr == NULL)
  220                 return (error);
  221         (*fp)(0x11111111, 0x22222222, 0x33333333);
  222         return (0);
  223 }
  224 
  225 void
  226 kdb_panic(const char *msg)
  227 {
  228         
  229 #ifdef SMP
  230         stop_cpus_hard(PCPU_GET(other_cpus));
  231 #endif
  232         printf("KDB: panic\n");
  233         panic(msg);
  234 }
  235 
  236 void
  237 kdb_reboot(void)
  238 {
  239 
  240         printf("KDB: reboot requested\n");
  241         shutdown_nice(0);
  242 }
  243 
  244 /*
  245  * Solaris implements a new BREAK which is initiated by a character sequence
  246  * CR ~ ^b which is similar to a familiar pattern used on Sun servers by the
  247  * Remote Console.
  248  *
  249  * Note that this function may be called from almost anywhere, with interrupts
  250  * disabled and with unknown locks held, so it must not access data other than
  251  * its arguments.  Its up to the caller to ensure that the state variable is
  252  * consistent.
  253  */
  254 
  255 #define KEY_CR          13      /* CR '\r' */
  256 #define KEY_TILDE       126     /* ~ */
  257 #define KEY_CRTLB       2       /* ^B */
  258 #define KEY_CRTLP       16      /* ^P */
  259 #define KEY_CRTLR       18      /* ^R */
  260 
  261 int
  262 kdb_alt_break(int key, int *state)
  263 {
  264         int brk;
  265 
  266         brk = 0;
  267         switch (*state) {
  268         case 0:
  269                 if (key == KEY_CR)
  270                         *state = 1;
  271                 break;
  272         case 1:
  273                 if (key == KEY_TILDE)
  274                         *state = 2;
  275                 break;
  276         case 2:
  277                 if (key == KEY_CRTLB)
  278                         brk = KDB_REQ_DEBUGGER;
  279                 else if (key == KEY_CRTLP)
  280                         brk = KDB_REQ_PANIC;
  281                 else if (key == KEY_CRTLR)
  282                         brk = KDB_REQ_REBOOT;
  283                 *state = 0;
  284         }
  285         return (brk);
  286 }
  287 
  288 /*
  289  * Print a backtrace of the calling thread. The backtrace is generated by
  290  * the selected debugger, provided it supports backtraces. If no debugger
  291  * is selected or the current debugger does not support backtraces, this
  292  * function silently returns.
  293  */
  294 
  295 void
  296 kdb_backtrace(void)
  297 {
  298 
  299         if (kdb_dbbe != NULL && kdb_dbbe->dbbe_trace != NULL) {
  300                 printf("KDB: stack backtrace:\n");
  301                 kdb_dbbe->dbbe_trace();
  302         }
  303 }
  304 
  305 /*
  306  * Set/change the current backend.
  307  */
  308 
  309 int
  310 kdb_dbbe_select(const char *name)
  311 {
  312         struct kdb_dbbe *be, **iter;
  313 
  314         SET_FOREACH(iter, kdb_dbbe_set) {
  315                 be = *iter;
  316                 if (be->dbbe_active == 0 && strcmp(be->dbbe_name, name) == 0) {
  317                         kdb_dbbe = be;
  318                         return (0);
  319                 }
  320         }
  321         return (EINVAL);
  322 }
  323 
  324 /*
  325  * Enter the currently selected debugger. If a message has been provided,
  326  * it is printed first. If the debugger does not support the enter method,
  327  * it is entered by using breakpoint(), which enters the debugger through
  328  * kdb_trap().  The 'why' argument will contain a more mechanically usable
  329  * string than 'msg', and is relied upon by DDB scripting to identify the
  330  * reason for entering the debugger so that the right script can be run.
  331  */
  332 void
  333 kdb_enter(const char *why, const char *msg)
  334 {
  335 
  336         if (kdb_dbbe != NULL && kdb_active == 0) {
  337                 if (msg != NULL)
  338                         printf("KDB: enter: %s\n", msg);
  339                 kdb_why = why;
  340                 breakpoint();
  341                 kdb_why = KDB_WHY_UNSET;
  342         }
  343 }
  344 
  345 /*
  346  * Initialize the kernel debugger interface.
  347  */
  348 
  349 void
  350 kdb_init(void)
  351 {
  352         struct kdb_dbbe *be, **iter;
  353         int cur_pri, pri;
  354 
  355         kdb_active = 0;
  356         kdb_dbbe = NULL;
  357         cur_pri = -1;
  358         SET_FOREACH(iter, kdb_dbbe_set) {
  359                 be = *iter;
  360                 pri = (be->dbbe_init != NULL) ? be->dbbe_init() : -1;
  361                 be->dbbe_active = (pri >= 0) ? 0 : -1;
  362                 if (pri > cur_pri) {
  363                         cur_pri = pri;
  364                         kdb_dbbe = be;
  365                 }
  366         }
  367         if (kdb_dbbe != NULL) {
  368                 printf("KDB: debugger backends:");
  369                 SET_FOREACH(iter, kdb_dbbe_set) {
  370                         be = *iter;
  371                         if (be->dbbe_active == 0)
  372                                 printf(" %s", be->dbbe_name);
  373                 }
  374                 printf("\n");
  375                 printf("KDB: current backend: %s\n",
  376                     kdb_dbbe->dbbe_name);
  377         }
  378 }
  379 
  380 /*
  381  * Handle contexts.
  382  */
  383 
  384 void *
  385 kdb_jmpbuf(jmp_buf new)
  386 {
  387         void *old;
  388 
  389         old = kdb_jmpbufp;
  390         kdb_jmpbufp = new;
  391         return (old);
  392 }
  393 
  394 void
  395 kdb_reenter(void)
  396 {
  397 
  398         if (!kdb_active || kdb_jmpbufp == NULL)
  399                 return;
  400 
  401         longjmp(kdb_jmpbufp, 1);
  402         /* NOTREACHED */
  403 }
  404 
  405 /*
  406  * Thread related support functions.
  407  */
  408 
  409 struct pcb *
  410 kdb_thr_ctx(struct thread *thr)
  411 {  
  412 #if defined(SMP) && defined(KDB_STOPPEDPCB)
  413         struct pcpu *pc;
  414 #endif
  415  
  416         if (thr == curthread) 
  417                 return (&kdb_pcb);
  418 
  419 #if defined(SMP) && defined(KDB_STOPPEDPCB)
  420         SLIST_FOREACH(pc, &cpuhead, pc_allcpu)  {
  421                 if (pc->pc_curthread == thr && (stopped_cpus & pc->pc_cpumask))
  422                         return (KDB_STOPPEDPCB(pc));
  423         }
  424 #endif
  425         return (thr->td_pcb);
  426 }
  427 
  428 struct thread *
  429 kdb_thr_first(void)
  430 {
  431         struct proc *p;
  432         struct thread *thr;
  433 
  434         p = LIST_FIRST(&allproc);
  435         while (p != NULL) {
  436                 if (p->p_flag & P_INMEM) {
  437                         thr = FIRST_THREAD_IN_PROC(p);
  438                         if (thr != NULL)
  439                                 return (thr);
  440                 }
  441                 p = LIST_NEXT(p, p_list);
  442         }
  443         return (NULL);
  444 }
  445 
  446 struct thread *
  447 kdb_thr_from_pid(pid_t pid)
  448 {
  449         struct proc *p;
  450 
  451         p = LIST_FIRST(&allproc);
  452         while (p != NULL) {
  453                 if (p->p_flag & P_INMEM && p->p_pid == pid)
  454                         return (FIRST_THREAD_IN_PROC(p));
  455                 p = LIST_NEXT(p, p_list);
  456         }
  457         return (NULL);
  458 }
  459 
  460 struct thread *
  461 kdb_thr_lookup(lwpid_t tid)
  462 {
  463         struct thread *thr;
  464 
  465         thr = kdb_thr_first();
  466         while (thr != NULL && thr->td_tid != tid)
  467                 thr = kdb_thr_next(thr);
  468         return (thr);
  469 }
  470 
  471 struct thread *
  472 kdb_thr_next(struct thread *thr)
  473 {
  474         struct proc *p;
  475 
  476         p = thr->td_proc;
  477         thr = TAILQ_NEXT(thr, td_plist);
  478         do {
  479                 if (thr != NULL)
  480                         return (thr);
  481                 p = LIST_NEXT(p, p_list);
  482                 if (p != NULL && (p->p_flag & P_INMEM))
  483                         thr = FIRST_THREAD_IN_PROC(p);
  484         } while (p != NULL);
  485         return (NULL);
  486 }
  487 
  488 int
  489 kdb_thr_select(struct thread *thr)
  490 {
  491         if (thr == NULL)
  492                 return (EINVAL);
  493         kdb_thread = thr;
  494         kdb_thrctx = kdb_thr_ctx(thr);
  495         return (0);
  496 }
  497 
  498 /*
  499  * Enter the debugger due to a trap.
  500  */
  501 
  502 int
  503 kdb_trap(int type, int code, struct trapframe *tf)
  504 {
  505         register_t intr;
  506 #ifdef SMP
  507         int did_stop_cpus;
  508 #endif
  509         int handled;
  510 
  511         if (kdb_dbbe == NULL || kdb_dbbe->dbbe_trap == NULL)
  512                 return (0);
  513 
  514         /* We reenter the debugger through kdb_reenter(). */
  515         if (kdb_active)
  516                 return (0);
  517 
  518         intr = intr_disable();
  519 
  520 #ifdef SMP
  521         if ((did_stop_cpus = kdb_stop_cpus) != 0)
  522                 stop_cpus_hard(PCPU_GET(other_cpus));
  523 #endif
  524 
  525         kdb_active++;
  526 
  527         kdb_frame = tf;
  528 
  529         /* Let MD code do its thing first... */
  530         kdb_cpu_trap(type, code);
  531 
  532         makectx(tf, &kdb_pcb);
  533         kdb_thr_select(curthread);
  534 
  535         handled = kdb_dbbe->dbbe_trap(type, code);
  536 
  537         kdb_active--;
  538 
  539 #ifdef SMP
  540         if (did_stop_cpus)
  541                 restart_cpus(stopped_cpus);
  542 #endif
  543 
  544         intr_restore(intr);
  545 
  546         return (handled);
  547 }

Cache object: 8da380dfd100c13a483517f29e05d2fd


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