From e8c0b1746f0409b2f2d252c0d3936dc163a8d472 Mon Sep 17 00:00:00 2001 From: kib Date: Sun, 19 Oct 2008 11:13:49 +0000 Subject: Ktr(9) stores format string and arguments in the event circular buffer, not the string formatted at the time of CTRX() call. Stack_ktr(9) uses an on-stack buffer for the symbol name, that is supplied as an argument to ktr. As result, stack_ktr() traces show garbage or cause page faults. Fix stack_ktr() by using pointer to module symbol table that is supposed to have a longer lifetime. Tested by: pho MFC after: 1 week --- sys/kern/subr_stack.c | 46 +++++++++++++++++++++++++--------------------- 1 file changed, 25 insertions(+), 21 deletions(-) diff --git a/sys/kern/subr_stack.c b/sys/kern/subr_stack.c index 0cd6909..cf7c7ac 100644 --- a/sys/kern/subr_stack.c +++ b/sys/kern/subr_stack.c @@ -45,8 +45,7 @@ static MALLOC_DEFINE(M_STACK, "stack", "Stack Traces"); static void stack_symbol(vm_offset_t pc, char *namebuf, u_int buflen, long *offset); #ifdef DDB -static void stack_symbol_ddb(vm_offset_t pc, char *namebuf, u_int buflen, - long *offset); +static void stack_symbol_ddb(vm_offset_t pc, const char **name, long *offset); #endif struct stack * @@ -109,16 +108,15 @@ stack_print(struct stack *st) void stack_print_ddb(struct stack *st) { - char namebuf[64]; + const char *name; long offset; int i; KASSERT(st->depth <= STACK_MAX, ("bogus stack")); for (i = 0; i < st->depth; i++) { - stack_symbol_ddb(st->pcs[i], namebuf, sizeof(namebuf), - &offset); + stack_symbol_ddb(st->pcs[i], &name, &offset); printf("#%d %p at %s+%#lx\n", i, (void *)st->pcs[i], - namebuf, offset); + name, offset); } } #endif @@ -146,16 +144,15 @@ stack_sbuf_print(struct sbuf *sb, struct stack *st) void stack_sbuf_print_ddb(struct sbuf *sb, struct stack *st) { - char namebuf[64]; + const char *name; long offset; int i; KASSERT(st->depth <= STACK_MAX, ("bogus stack")); for (i = 0; i < st->depth; i++) { - stack_symbol_ddb(st->pcs[i], namebuf, sizeof(namebuf), - &offset); + stack_symbol_ddb(st->pcs[i], &name, &offset); sbuf_printf(sb, "#%d %p at %s+%#lx\n", i, (void *)st->pcs[i], - namebuf, offset); + name, offset); } } @@ -164,7 +161,7 @@ void stack_ktr(u_int mask, const char *file, int line, struct stack *st, u_int depth, int cheap) { - char namebuf[64]; + const char *name; long offset; int i; @@ -187,10 +184,9 @@ stack_ktr(u_int mask, const char *file, int line, struct stack *st, u_int depth, if (depth == 0 || st->depth < depth) depth = st->depth; for (i = 0; i < depth; i++) { - stack_symbol_ddb(st->pcs[i], namebuf, - sizeof(namebuf), &offset); + stack_symbol_ddb(st->pcs[i], &name, &offset); ktr_tracepoint(mask, file, line, "#%d %p at %s+%#lx", - i, st->pcs[i], (u_long)namebuf, offset, 0, 0); + i, st->pcs[i], (u_long)name, offset, 0, 0); } } } @@ -214,13 +210,21 @@ stack_symbol(vm_offset_t pc, char *namebuf, u_int buflen, long *offset) #ifdef DDB static void -stack_symbol_ddb(vm_offset_t pc, char *namebuf, u_int buflen, long *offset) +stack_symbol_ddb(vm_offset_t pc, const char **name, long *offset) { - - if (linker_ddb_search_symbol_name((caddr_t)pc, namebuf, buflen, - offset) != 0) { - *offset = 0; - strlcpy(namebuf, "??", buflen); - }; + linker_symval_t symval; + c_linker_sym_t sym; + + if (linker_ddb_search_symbol((caddr_t)pc, &sym, offset) != 0) + goto out; + if (linker_ddb_symbol_values(sym, &symval) != 0) + goto out; + if (symval.name != NULL) { + *name = symval.name; + return; + } + out: + *offset = 0; + *name = "??"; } #endif -- cgit v1.1