subr_stack.c (09c817ba36db7c3a4ff5e25ac55816ca181a403d) | subr_stack.c (8d511e2a05455bb7971ee943e6691159c189417b) |
---|---|
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 --- 10 unchanged lines hidden (view full) --- 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 | 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 --- 10 unchanged lines hidden (view full) --- 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 | 27#include <sys/cdefs.h> 28__FBSDID("$FreeBSD$"); 29 30#include <sys/param.h> 31#include <sys/kernel.h> 32#ifdef KTR 33#include <sys/ktr.h> 34#endif 35#include <sys/linker.h> 36#include <sys/malloc.h> 37#include <sys/sbuf.h> 38#include <sys/stack.h> 39#include <sys/systm.h> 40 |
43static MALLOC_DEFINE(M_STACK, "stack", "Stack Traces"); | 41MALLOC_DEFINE(M_STACK, "stack", "Stack Traces"); |
44 | 42 |
45static int stack_symbol(vm_offset_t pc, char *namebuf, u_int buflen, 46 long *offset); 47#ifdef DDB 48static int stack_symbol_ddb(vm_offset_t pc, const char **name, long *offset); 49#endif | 43static void stack_symbol(vm_offset_t pc, const char **name, long *offset); |
50 51struct stack * 52stack_create(void) 53{ 54 struct stack *st; 55 56 st = malloc(sizeof *st, M_STACK, M_WAITOK | M_ZERO); 57 return (st); --- 29 unchanged lines hidden (view full) --- 87{ 88 89 bzero(st, sizeof *st); 90} 91 92void 93stack_print(struct stack *st) 94{ | 44 45struct stack * 46stack_create(void) 47{ 48 struct stack *st; 49 50 st = malloc(sizeof *st, M_STACK, M_WAITOK | M_ZERO); 51 return (st); --- 29 unchanged lines hidden (view full) --- 81{ 82 83 bzero(st, sizeof *st); 84} 85 86void 87stack_print(struct stack *st) 88{ |
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 (void)stack_symbol(st->pcs[i], namebuf, sizeof(namebuf), 102 &offset); 103 printf("#%d %p at %s+%#lx\n", i, (void *)st->pcs[i], 104 namebuf, offset); 105 } 106} 107 108void 109stack_print_short(struct stack *st) 110{ 111 char namebuf[64]; 112 long offset; 113 int i; 114 115 KASSERT(st->depth <= STACK_MAX, ("bogus stack")); 116 for (i = 0; i < st->depth; i++) { 117 if (i > 0) 118 printf(" "); 119 if (stack_symbol(st->pcs[i], namebuf, sizeof(namebuf), 120 &offset) == 0) 121 printf("%s+%#lx", namebuf, offset); 122 else 123 printf("%p", (void *)st->pcs[i]); 124 } 125 printf("\n"); 126} 127 128#ifdef DDB 129void 130stack_print_ddb(struct stack *st) 131{ | |
132 const char *name; 133 long offset; 134 int i; 135 | 89 const char *name; 90 long offset; 91 int i; 92 |
136 KASSERT(st->depth <= STACK_MAX, ("bogus stack")); | 93 KASSERT(st->depth <= STACK_MAX, ("bogous stack")); |
137 for (i = 0; i < st->depth; i++) { | 94 for (i = 0; i < st->depth; i++) { |
138 stack_symbol_ddb(st->pcs[i], &name, &offset); | 95 stack_symbol(st->pcs[i], &name, &offset); |
139 printf("#%d %p at %s+%#lx\n", i, (void *)st->pcs[i], 140 name, offset); 141 } 142} 143 144void | 96 printf("#%d %p at %s+%#lx\n", i, (void *)st->pcs[i], 97 name, offset); 98 } 99} 100 101void |
145stack_print_short_ddb(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 if (i > 0) 154 printf(" "); 155 if (stack_symbol_ddb(st->pcs[i], &name, &offset) == 0) 156 printf("%s+%#lx", name, offset); 157 else 158 printf("%p", (void *)st->pcs[i]); 159 } 160 printf("\n"); 161} 162#endif 163 164/* 165 * Two print routines -- one for use from DDB and DDB-like contexts, the 166 * other for use in the live kernel. 167 */ 168void | |
169stack_sbuf_print(struct sbuf *sb, struct stack *st) 170{ | 102stack_sbuf_print(struct sbuf *sb, struct stack *st) 103{ |
171 char namebuf[64]; 172 long offset; 173 int i; 174 175 KASSERT(st->depth <= STACK_MAX, ("bogus stack")); 176 for (i = 0; i < st->depth; i++) { 177 (void)stack_symbol(st->pcs[i], namebuf, sizeof(namebuf), 178 &offset); 179 sbuf_printf(sb, "#%d %p at %s+%#lx\n", i, (void *)st->pcs[i], 180 namebuf, offset); 181 } 182} 183 184#ifdef DDB 185void 186stack_sbuf_print_ddb(struct sbuf *sb, struct stack *st) 187{ | |
188 const char *name; 189 long offset; 190 int i; 191 | 104 const char *name; 105 long offset; 106 int i; 107 |
192 KASSERT(st->depth <= STACK_MAX, ("bogus stack")); | 108 KASSERT(st->depth <= STACK_MAX, ("bogous stack")); |
193 for (i = 0; i < st->depth; i++) { | 109 for (i = 0; i < st->depth; i++) { |
194 (void)stack_symbol_ddb(st->pcs[i], &name, &offset); | 110 stack_symbol(st->pcs[i], &name, &offset); |
195 sbuf_printf(sb, "#%d %p at %s+%#lx\n", i, (void *)st->pcs[i], 196 name, offset); 197 } 198} | 111 sbuf_printf(sb, "#%d %p at %s+%#lx\n", i, (void *)st->pcs[i], 112 name, offset); 113 } 114} |
199#endif | |
200 201#ifdef KTR 202void | 115 116#ifdef KTR 117void |
203stack_ktr(u_int mask, const char *file, int line, struct stack *st, u_int depth, 204 int cheap) | 118stack_ktr(u_int mask, const char *file, int line, struct stack *st, int cheap) |
205{ | 119{ |
206#ifdef DDB | |
207 const char *name; 208 long offset; 209 int i; | 120 const char *name; 121 long offset; 122 int i; |
210#endif | |
211 | 123 |
212 KASSERT(st->depth <= STACK_MAX, ("bogus stack")); | 124 KASSERT(st->depth <= STACK_MAX, ("bogous stack")); |
213 if (cheap) { 214 ktr_tracepoint(mask, file, line, "#0 %p %p %p %p %p %p", 215 st->pcs[0], st->pcs[1], st->pcs[2], st->pcs[3], 216 st->pcs[4], st->pcs[5]); 217 if (st->depth <= 6) 218 return; 219 ktr_tracepoint(mask, file, line, "#1 %p %p %p %p %p %p", 220 st->pcs[6], st->pcs[7], st->pcs[8], st->pcs[9], 221 st->pcs[10], st->pcs[11]); 222 if (st->depth <= 12) 223 return; 224 ktr_tracepoint(mask, file, line, "#2 %p %p %p %p %p %p", 225 st->pcs[12], st->pcs[13], st->pcs[14], st->pcs[15], 226 st->pcs[16], st->pcs[17]); | 125 if (cheap) { 126 ktr_tracepoint(mask, file, line, "#0 %p %p %p %p %p %p", 127 st->pcs[0], st->pcs[1], st->pcs[2], st->pcs[3], 128 st->pcs[4], st->pcs[5]); 129 if (st->depth <= 6) 130 return; 131 ktr_tracepoint(mask, file, line, "#1 %p %p %p %p %p %p", 132 st->pcs[6], st->pcs[7], st->pcs[8], st->pcs[9], 133 st->pcs[10], st->pcs[11]); 134 if (st->depth <= 12) 135 return; 136 ktr_tracepoint(mask, file, line, "#2 %p %p %p %p %p %p", 137 st->pcs[12], st->pcs[13], st->pcs[14], st->pcs[15], 138 st->pcs[16], st->pcs[17]); |
227#ifdef DDB 228 } else { 229 if (depth == 0 || st->depth < depth) 230 depth = st->depth; 231 for (i = 0; i < depth; i++) { 232 (void)stack_symbol_ddb(st->pcs[i], &name, &offset); | 139 } else 140 for (i = 0; i < st->depth; i++) { 141 stack_symbol(st->pcs[i], &name, &offset); |
233 ktr_tracepoint(mask, file, line, "#%d %p at %s+%#lx", 234 i, st->pcs[i], (u_long)name, offset, 0, 0); 235 } | 142 ktr_tracepoint(mask, file, line, "#%d %p at %s+%#lx", 143 i, st->pcs[i], (u_long)name, offset, 0, 0); 144 } |
236#endif 237 } | |
238} 239#endif 240 | 145} 146#endif 147 |
241/* 242 * Two variants of stack symbol lookup -- one that uses the DDB interfaces 243 * and bypasses linker locking, and the other that doesn't. 244 */ 245static int 246stack_symbol(vm_offset_t pc, char *namebuf, u_int buflen, long *offset) | 148static void 149stack_symbol(vm_offset_t pc, const char **name, long *offset) |
247{ | 150{ |
248 249 if (linker_search_symbol_name((caddr_t)pc, namebuf, buflen, 250 offset) != 0) { 251 *offset = 0; 252 strlcpy(namebuf, "??", buflen); 253 return (ENOENT); 254 } else 255 return (0); 256} 257 258#ifdef DDB 259static int 260stack_symbol_ddb(vm_offset_t pc, const char **name, long *offset) 261{ | |
262 linker_symval_t symval; 263 c_linker_sym_t sym; 264 265 if (linker_ddb_search_symbol((caddr_t)pc, &sym, offset) != 0) 266 goto out; 267 if (linker_ddb_symbol_values(sym, &symval) != 0) 268 goto out; 269 if (symval.name != NULL) { 270 *name = symval.name; | 151 linker_symval_t symval; 152 c_linker_sym_t sym; 153 154 if (linker_ddb_search_symbol((caddr_t)pc, &sym, offset) != 0) 155 goto out; 156 if (linker_ddb_symbol_values(sym, &symval) != 0) 157 goto out; 158 if (symval.name != NULL) { 159 *name = symval.name; |
271 return (0); | 160 return; |
272 } | 161 } |
273 out: | 162out: |
274 *offset = 0; | 163 *offset = 0; |
275 *name = "??"; 276 return (ENOENT); | 164 *name = "Unknown func"; |
277} | 165} |
278#endif | |