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/5.3/sys/kern/subr_kdb.c 136588 2004-10-16 08:43:07Z cvs2svn $");
   29 
   30 #include <sys/param.h>
   31 #include <sys/systm.h>
   32 #include <sys/kdb.h>
   33 #include <sys/kernel.h>
   34 #include <sys/malloc.h>
   35 #include <sys/pcpu.h>
   36 #include <sys/proc.h>
   37 #include <sys/smp.h>
   38 #include <sys/sysctl.h>
   39 
   40 #include <machine/kdb.h>
   41 #include <machine/pcb.h>
   42 
   43 int kdb_active = 0;
   44 void *kdb_jmpbufp = NULL;
   45 struct kdb_dbbe *kdb_dbbe = NULL;
   46 struct pcb kdb_pcb;
   47 struct pcb *kdb_thrctx = NULL;
   48 struct thread *kdb_thread = NULL;
   49 struct trapframe *kdb_frame = NULL;
   50 
   51 KDB_BACKEND(null, NULL, NULL, NULL);
   52 SET_DECLARE(kdb_dbbe_set, struct kdb_dbbe);
   53 
   54 static int kdb_sysctl_available(SYSCTL_HANDLER_ARGS);
   55 static int kdb_sysctl_current(SYSCTL_HANDLER_ARGS);
   56 static int kdb_sysctl_enter(SYSCTL_HANDLER_ARGS);
   57 
   58 SYSCTL_NODE(_debug, OID_AUTO, kdb, CTLFLAG_RW, NULL, "KDB nodes");
   59 
   60 SYSCTL_PROC(_debug_kdb, OID_AUTO, available, CTLTYPE_STRING | CTLFLAG_RD, 0, 0,
   61     kdb_sysctl_available, "A", "list of available KDB backends");
   62 
   63 SYSCTL_PROC(_debug_kdb, OID_AUTO, current, CTLTYPE_STRING | CTLFLAG_RW, 0, 0,
   64     kdb_sysctl_current, "A", "currently selected KDB backend");
   65 
   66 SYSCTL_PROC(_debug_kdb, OID_AUTO, enter, CTLTYPE_INT | CTLFLAG_RW, 0, 0,
   67     kdb_sysctl_enter, "I", "set to enter the debugger");
   68 
   69 /*
   70  * Flag indicating whether or not to IPI the other CPUs to stop them on
   71  * entering the debugger.  Sometimes, this will result in a deadlock as
   72  * stop_cpus() waits for the other cpus to stop, so we allow it to be
   73  * disabled.
   74  */
   75 #ifdef SMP
   76 static int kdb_stop_cpus = 1;
   77 SYSCTL_INT(_debug_kdb, OID_AUTO, stop_cpus, CTLTYPE_INT | CTLFLAG_RW,
   78     &kdb_stop_cpus, 0, "");
   79 TUNABLE_INT("debug.kdb.stop_cpus", &kdb_stop_cpus);
   80 #endif
   81 
   82 static int
   83 kdb_sysctl_available(SYSCTL_HANDLER_ARGS)
   84 {
   85         struct kdb_dbbe *be, **iter;
   86         char *avail, *p;
   87         ssize_t len, sz;
   88         int error;
   89 
   90         sz = 0;
   91         SET_FOREACH(iter, kdb_dbbe_set) {
   92                 be = *iter;
   93                 if (be->dbbe_active == 0)
   94                         sz += strlen(be->dbbe_name) + 1;
   95         }
   96         sz++;
   97         avail = malloc(sz, M_TEMP, M_WAITOK);
   98         p = avail;
   99         SET_FOREACH(iter, kdb_dbbe_set) {
  100                 be = *iter;
  101                 if (be->dbbe_active == 0) {
  102                         len = snprintf(p, sz, "%s ", be->dbbe_name);
  103                         p += len;
  104                         sz -= len;
  105                 }
  106         }
  107         KASSERT(sz >= 0, ("%s", __func__));
  108         error = sysctl_handle_string(oidp, avail, 0, req);
  109         free(avail, M_TEMP);
  110         return (error);
  111 }
  112 
  113 static int
  114 kdb_sysctl_current(SYSCTL_HANDLER_ARGS)
  115 {
  116         char buf[16];
  117         int error;
  118 
  119         if (kdb_dbbe != NULL) {
  120                 strncpy(buf, kdb_dbbe->dbbe_name, sizeof(buf));
  121                 buf[sizeof(buf) - 1] = '\0';
  122         } else
  123                 *buf = '\0';
  124         error = sysctl_handle_string(oidp, buf, sizeof(buf), req);
  125         if (error != 0 || req->newptr == NULL)
  126                 return (error);
  127         if (kdb_active)
  128                 return (EBUSY);
  129         return (kdb_dbbe_select(buf));
  130 }
  131 
  132 static int
  133 kdb_sysctl_enter(SYSCTL_HANDLER_ARGS)
  134 {
  135         int error, i;
  136 
  137         error = sysctl_wire_old_buffer(req, sizeof(int));
  138         if (error == 0) {
  139                 i = 0;
  140                 error = sysctl_handle_int(oidp, &i, 0, req);
  141         }
  142         if (error != 0 || req->newptr == NULL)
  143                 return (error);
  144         if (kdb_active)
  145                 return (EBUSY);
  146         kdb_enter("sysctl debug.kdb.enter");
  147         return (0);
  148 }
  149 
  150 /*
  151  * Solaris implements a new BREAK which is initiated by a character sequence
  152  * CR ~ ^b which is similar to a familiar pattern used on Sun servers by the
  153  * Remote Console.
  154  *
  155  * Note that this function may be called from almost anywhere, with interrupts
  156  * disabled and with unknown locks held, so it must not access data other than
  157  * its arguments.  Its up to the caller to ensure that the state variable is
  158  * consistent.
  159  */
  160 
  161 #define KEY_CR          13      /* CR '\r' */
  162 #define KEY_TILDE       126     /* ~ */
  163 #define KEY_CRTLB       2       /* ^B */
  164 
  165 int
  166 kdb_alt_break(int key, int *state)
  167 {
  168         int brk;
  169 
  170         brk = 0;
  171         switch (key) {
  172         case KEY_CR:
  173                 *state = KEY_TILDE;
  174                 break;
  175         case KEY_TILDE:
  176                 *state = (*state == KEY_TILDE) ? KEY_CRTLB : 0;
  177                 break;
  178         case KEY_CRTLB:
  179                 if (*state == KEY_CRTLB)
  180                         brk = 1;
  181                 /* FALLTHROUGH */
  182         default:
  183                 *state = 0;
  184                 break;
  185         }
  186         return (brk);
  187 }
  188 
  189 /*
  190  * Print a backtrace of the calling thread. The backtrace is generated by
  191  * the selected debugger, provided it supports backtraces. If no debugger
  192  * is selected or the current debugger does not support backtraces, this
  193  * function silently returns.
  194  */
  195 
  196 void
  197 kdb_backtrace()
  198 {
  199 
  200         if (kdb_dbbe != NULL && kdb_dbbe->dbbe_trace != NULL) {
  201                 printf("KDB: stack backtrace:\n");
  202                 kdb_dbbe->dbbe_trace();
  203         }
  204 }
  205 
  206 /*
  207  * Set/change the current backend.
  208  */
  209 
  210 int
  211 kdb_dbbe_select(const char *name)
  212 {
  213         struct kdb_dbbe *be, **iter;
  214 
  215         SET_FOREACH(iter, kdb_dbbe_set) {
  216                 be = *iter;
  217                 if (be->dbbe_active == 0 && strcmp(be->dbbe_name, name) == 0) {
  218                         kdb_dbbe = be;
  219                         return (0);
  220                 }
  221         }
  222         return (EINVAL);
  223 }
  224 
  225 /*
  226  * Enter the currently selected debugger. If a message has been provided,
  227  * it is printed first. If the debugger does not support the enter method,
  228  * it is entered by using breakpoint(), which enters the debugger through
  229  * kdb_trap().
  230  */
  231 
  232 void
  233 kdb_enter(const char *msg)
  234 {
  235 
  236         if (kdb_dbbe != NULL && kdb_active == 0) {
  237                 if (msg != NULL)
  238                         printf("KDB: enter: %s\n", msg);
  239                 breakpoint();
  240         }
  241 }
  242 
  243 /*
  244  * Initialize the kernel debugger interface.
  245  */
  246 
  247 void
  248 kdb_init()
  249 {
  250         struct kdb_dbbe *be, **iter;
  251         int cur_pri, pri;
  252 
  253         kdb_active = 0;
  254         kdb_dbbe = NULL;
  255         cur_pri = -1;
  256         SET_FOREACH(iter, kdb_dbbe_set) {
  257                 be = *iter;
  258                 pri = (be->dbbe_init != NULL) ? be->dbbe_init() : -1;
  259                 be->dbbe_active = (pri >= 0) ? 0 : -1;
  260                 if (pri > cur_pri) {
  261                         cur_pri = pri;
  262                         kdb_dbbe = be;
  263                 }
  264         }
  265         if (kdb_dbbe != NULL) {
  266                 printf("KDB: debugger backends:");
  267                 SET_FOREACH(iter, kdb_dbbe_set) {
  268                         be = *iter;
  269                         if (be->dbbe_active == 0)
  270                                 printf(" %s", be->dbbe_name);
  271                 }
  272                 printf("\n");
  273                 printf("KDB: current backend: %s\n",
  274                     kdb_dbbe->dbbe_name);
  275         }
  276 }
  277 
  278 /*
  279  * Handle contexts.
  280  */
  281 
  282 void *
  283 kdb_jmpbuf(jmp_buf new)
  284 {
  285         void *old;
  286 
  287         old = kdb_jmpbufp;
  288         kdb_jmpbufp = new;
  289         return (old);
  290 }
  291 
  292 void
  293 kdb_reenter(void)
  294 {
  295 
  296         if (!kdb_active || kdb_jmpbufp == NULL)
  297                 return;
  298 
  299         longjmp(kdb_jmpbufp, 1);
  300         /* NOTREACHED */
  301 }
  302 
  303 /*
  304  * Thread related support functions.
  305  */
  306 
  307 struct pcb *
  308 kdb_thr_ctx(struct thread *thr)
  309 {
  310         return ((thr == curthread) ? &kdb_pcb : thr->td_pcb);
  311 }
  312 
  313 struct thread *
  314 kdb_thr_first(void)
  315 {
  316         struct proc *p;
  317         struct thread *thr;
  318 
  319         p = LIST_FIRST(&allproc);
  320         while (p != NULL) {
  321                 if (p->p_sflag & PS_INMEM) {
  322                         thr = FIRST_THREAD_IN_PROC(p);
  323                         if (thr != NULL)
  324                                 return (thr);
  325                 }
  326                 p = LIST_NEXT(p, p_list);
  327         }
  328         return (NULL);
  329 }
  330 
  331 struct thread *
  332 kdb_thr_from_pid(pid_t pid)
  333 {
  334         struct proc *p;
  335 
  336         p = LIST_FIRST(&allproc);
  337         while (p != NULL) {
  338                 if (p->p_sflag & PS_INMEM && p->p_pid == pid)
  339                         return (FIRST_THREAD_IN_PROC(p));
  340                 p = LIST_NEXT(p, p_list);
  341         }
  342         return (NULL);
  343 }
  344 
  345 struct thread *
  346 kdb_thr_lookup(lwpid_t tid)
  347 {
  348         struct thread *thr;
  349 
  350         thr = kdb_thr_first();
  351         while (thr != NULL && thr->td_tid != tid)
  352                 thr = kdb_thr_next(thr);
  353         return (thr);
  354 }
  355 
  356 struct thread *
  357 kdb_thr_next(struct thread *thr)
  358 {
  359         struct proc *p;
  360 
  361         p = thr->td_proc;
  362         thr = TAILQ_NEXT(thr, td_plist);
  363         do {
  364                 if (thr != NULL)
  365                         return (thr);
  366                 p = LIST_NEXT(p, p_list);
  367                 if (p != NULL && (p->p_sflag & PS_INMEM))
  368                         thr = FIRST_THREAD_IN_PROC(p);
  369         } while (p != NULL);
  370         return (NULL);
  371 }
  372 
  373 int
  374 kdb_thr_select(struct thread *thr)
  375 {
  376         if (thr == NULL)
  377                 return (EINVAL);
  378         kdb_thread = thr;
  379         kdb_thrctx = kdb_thr_ctx(thr);
  380         return (0);
  381 }
  382 
  383 /*
  384  * Enter the debugger due to a trap.
  385  */
  386 
  387 int
  388 kdb_trap(int type, int code, struct trapframe *tf)
  389 {
  390 #ifdef SMP
  391         int did_stop_cpus;
  392 #endif
  393         int handled;
  394 
  395         if (kdb_dbbe == NULL || kdb_dbbe->dbbe_trap == NULL)
  396                 return (0);
  397 
  398         /* We reenter the debugger through kdb_reenter(). */
  399         if (kdb_active)
  400                 return (0);
  401 
  402         makectx(tf, &kdb_pcb);
  403 
  404         critical_enter();
  405 
  406         kdb_active++;
  407         kdb_frame = tf;
  408         kdb_thr_select(curthread);
  409 
  410 #ifdef SMP
  411         if ((did_stop_cpus = kdb_stop_cpus) != 0)
  412                 stop_cpus(PCPU_GET(other_cpus));
  413 #endif
  414 
  415         /* Let MD code do its thing first... */
  416         kdb_cpu_trap(type, code);
  417 
  418         handled = kdb_dbbe->dbbe_trap(type, code);
  419 
  420 #ifdef SMP
  421         if (did_stop_cpus)
  422                 restart_cpus(stopped_cpus);
  423 #endif
  424 
  425         kdb_active--;
  426 
  427         critical_exit();
  428 
  429         return (handled);
  430 }

Cache object: 930da381660f099c05deeb33c4214a40


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