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

Cache object: 3d994e05f4d17992b5ae6e0d89ecd65e


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