summaryrefslogtreecommitdiffstats
path: root/sys/kern/subr_stack.c
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2008-10-19 11:13:49 +0000
committerkib <kib@FreeBSD.org>2008-10-19 11:13:49 +0000
commite8c0b1746f0409b2f2d252c0d3936dc163a8d472 (patch)
tree9d3eaeedec2da498c5c435a18b4b992d9dfcf93c /sys/kern/subr_stack.c
parent4360de0fd47f3d750baf7e052028a69f7a3d72cf (diff)
downloadFreeBSD-src-e8c0b1746f0409b2f2d252c0d3936dc163a8d472.zip
FreeBSD-src-e8c0b1746f0409b2f2d252c0d3936dc163a8d472.tar.gz
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
Diffstat (limited to 'sys/kern/subr_stack.c')
-rw-r--r--sys/kern/subr_stack.c46
1 files 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
OpenPOWER on IntegriCloud