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_stack.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) 2005 Antoine Brodin
    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  * 1. Redistributions of source code must retain the above copyright
    9  *    notice, this list of conditions and the following disclaimer.
   10  * 2. Redistributions in binary form must reproduce the above copyright
   11  *    notice, this list of conditions and the following disclaimer in the
   12  *    documentation and/or other materials provided with the distribution.
   13  *
   14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   24  * SUCH DAMAGE.
   25  */
   26 
   27 #include "opt_ddb.h"
   28 
   29 #include <sys/cdefs.h>
   30 __FBSDID("$FreeBSD$");
   31 
   32 #include <sys/param.h>
   33 #include <sys/kernel.h>
   34 #ifdef KTR
   35 #include <sys/ktr.h>
   36 #endif
   37 #include <sys/linker.h>
   38 #include <sys/malloc.h>
   39 #include <sys/sbuf.h>
   40 #include <sys/stack.h>
   41 #include <sys/systm.h>
   42 
   43 static MALLOC_DEFINE(M_STACK, "stack", "Stack Traces");
   44 
   45 static void stack_symbol(vm_offset_t pc, char *namebuf, u_int buflen,
   46             long *offset);
   47 #ifdef DDB
   48 static void stack_symbol_ddb(vm_offset_t pc, const char **name, long *offset);
   49 #endif
   50 
   51 struct stack *
   52 stack_create(void)
   53 {
   54         struct stack *st;
   55 
   56         st = malloc(sizeof *st, M_STACK, M_WAITOK | M_ZERO);
   57         return (st);
   58 }
   59 
   60 void
   61 stack_destroy(struct stack *st)
   62 {
   63 
   64         free(st, M_STACK);
   65 }
   66 
   67 int
   68 stack_put(struct stack *st, vm_offset_t pc)
   69 {
   70 
   71         if (st->depth < STACK_MAX) {
   72                 st->pcs[st->depth++] = pc;
   73                 return (0);
   74         } else
   75                 return (-1);
   76 }
   77 
   78 void
   79 stack_copy(struct stack *src, struct stack *dst)
   80 {
   81 
   82         *dst = *src;
   83 }
   84 
   85 void
   86 stack_zero(struct stack *st)
   87 {
   88 
   89         bzero(st, sizeof *st);
   90 }
   91 
   92 void
   93 stack_print(struct stack *st)
   94 {
   95         char namebuf[64];
   96         long offset;
   97         int i;
   98 
   99         KASSERT(st->depth <= STACK_MAX, ("bogus stack"));
  100         for (i = 0; i < st->depth; i++) {
  101                 stack_symbol(st->pcs[i], namebuf, sizeof(namebuf), &offset);
  102                 printf("#%d %p at %s+%#lx\n", i, (void *)st->pcs[i],
  103                     namebuf, offset);
  104         }
  105 }
  106 
  107 #ifdef DDB
  108 void
  109 stack_print_ddb(struct stack *st)
  110 {
  111         const char *name;
  112         long offset;
  113         int i;
  114 
  115         KASSERT(st->depth <= STACK_MAX, ("bogus stack"));
  116         for (i = 0; i < st->depth; i++) {
  117                 stack_symbol_ddb(st->pcs[i], &name, &offset);
  118                 printf("#%d %p at %s+%#lx\n", i, (void *)st->pcs[i],
  119                     name, offset);
  120         }
  121 }
  122 #endif
  123 
  124 /*
  125  * Two print routines -- one for use from DDB and DDB-like contexts, the
  126  * other for use in the live kernel.
  127  */
  128 void
  129 stack_sbuf_print(struct sbuf *sb, struct stack *st)
  130 {
  131         char namebuf[64];
  132         long offset;
  133         int i;
  134 
  135         KASSERT(st->depth <= STACK_MAX, ("bogus stack"));
  136         for (i = 0; i < st->depth; i++) {
  137                 stack_symbol(st->pcs[i], namebuf, sizeof(namebuf), &offset);
  138                 sbuf_printf(sb, "#%d %p at %s+%#lx\n", i, (void *)st->pcs[i],
  139                     namebuf, offset);
  140         }
  141 }
  142 
  143 #ifdef DDB
  144 void
  145 stack_sbuf_print_ddb(struct sbuf *sb, struct stack *st)
  146 {
  147         const char *name;
  148         long offset;
  149         int i;
  150 
  151         KASSERT(st->depth <= STACK_MAX, ("bogus stack"));
  152         for (i = 0; i < st->depth; i++) {
  153                 stack_symbol_ddb(st->pcs[i], &name, &offset);
  154                 sbuf_printf(sb, "#%d %p at %s+%#lx\n", i, (void *)st->pcs[i],
  155                     name, offset);
  156         }
  157 }
  158 
  159 #ifdef KTR
  160 void
  161 stack_ktr(u_int mask, const char *file, int line, struct stack *st, u_int depth,
  162     int cheap)
  163 {
  164         const char *name;
  165         long offset;
  166         int i;
  167 
  168         KASSERT(st->depth <= STACK_MAX, ("bogus stack"));
  169         if (cheap) {
  170                 ktr_tracepoint(mask, file, line, "#0 %p %p %p %p %p %p",
  171                     st->pcs[0], st->pcs[1], st->pcs[2], st->pcs[3],
  172                     st->pcs[4], st->pcs[5]);
  173                 if (st->depth <= 6)
  174                         return;
  175                 ktr_tracepoint(mask, file, line, "#1 %p %p %p %p %p %p",
  176                     st->pcs[6], st->pcs[7], st->pcs[8], st->pcs[9],
  177                     st->pcs[10], st->pcs[11]);
  178                 if (st->depth <= 12)
  179                         return;
  180                 ktr_tracepoint(mask, file, line, "#2 %p %p %p %p %p %p",
  181                     st->pcs[12], st->pcs[13], st->pcs[14], st->pcs[15],
  182                     st->pcs[16], st->pcs[17]);
  183         } else {
  184                 if (depth == 0 || st->depth < depth)
  185                         depth = st->depth;
  186                 for (i = 0; i < depth; i++) {
  187                         stack_symbol_ddb(st->pcs[i], &name, &offset);
  188                         ktr_tracepoint(mask, file, line, "#%d %p at %s+%#lx",
  189                             i, st->pcs[i], (u_long)name, offset, 0, 0);
  190                 }
  191         }
  192 }
  193 #endif
  194 #endif
  195 
  196 /*
  197  * Two variants of stack symbol lookup -- one that uses the DDB interfaces
  198  * and bypasses linker locking, and the other that doesn't.
  199  */
  200 static void
  201 stack_symbol(vm_offset_t pc, char *namebuf, u_int buflen, long *offset)
  202 {
  203 
  204         if (linker_search_symbol_name((caddr_t)pc, namebuf, buflen,
  205             offset) != 0) {
  206                 *offset = 0;
  207                 strlcpy(namebuf, "??", buflen);
  208         }
  209 }
  210 
  211 #ifdef DDB
  212 static void
  213 stack_symbol_ddb(vm_offset_t pc, const char **name, long *offset)
  214 {
  215         linker_symval_t symval;
  216         c_linker_sym_t sym;
  217 
  218         if (linker_ddb_search_symbol((caddr_t)pc, &sym, offset) != 0)
  219                 goto out;
  220         if (linker_ddb_symbol_values(sym, &symval) != 0)
  221                 goto out;
  222         if (symval.name != NULL) {
  223                 *name = symval.name;
  224                 return;
  225         }
  226  out:
  227         *offset = 0;
  228         *name = "??";
  229 }
  230 #endif

Cache object: 1c586fc74788a9b71fbdd248d573f470


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