Index: head/sys/kern/kern_linker.c =================================================================== --- head/sys/kern/kern_linker.c +++ head/sys/kern/kern_linker.c @@ -1021,15 +1021,33 @@ * obey locking protocols, and offer a significantly less complex interface. */ int -linker_search_symbol_name(caddr_t value, char *buf, u_int buflen, - long *offset) +linker_search_symbol_name_flags(caddr_t value, char *buf, u_int buflen, + long *offset, int flags) { int error; - sx_slock(&kld_sx); + KASSERT((flags & (M_NOWAIT | M_WAITOK)) != 0 && + (flags & (M_NOWAIT | M_WAITOK)) != (M_NOWAIT | M_WAITOK), + ("%s: bad flags: 0x%x", __func__, flags)); + + if (flags & M_NOWAIT) { + if (!sx_try_slock(&kld_sx)) + return (EWOULDBLOCK); + } else + sx_slock(&kld_sx); + error = linker_debug_search_symbol_name(value, buf, buflen, offset); sx_sunlock(&kld_sx); return (error); +} + +int +linker_search_symbol_name(caddr_t value, char *buf, u_int buflen, + long *offset) +{ + + return (linker_search_symbol_name_flags(value, buf, buflen, offset, + M_WAITOK)); } /* Index: head/sys/kern/subr_stack.c =================================================================== --- head/sys/kern/subr_stack.c +++ head/sys/kern/subr_stack.c @@ -48,7 +48,7 @@ static MALLOC_DEFINE(M_STACK, "stack", "Stack Traces"); static int stack_symbol(vm_offset_t pc, char *namebuf, u_int buflen, - long *offset); + long *offset, int flags); static int stack_symbol_ddb(vm_offset_t pc, const char **name, long *offset); struct stack * @@ -102,7 +102,7 @@ KASSERT(st->depth <= STACK_MAX, ("bogus stack")); for (i = 0; i < st->depth; i++) { (void)stack_symbol(st->pcs[i], namebuf, sizeof(namebuf), - &offset); + &offset, M_WAITOK); printf("#%d %p at %s+%#lx\n", i, (void *)st->pcs[i], namebuf, offset); } @@ -120,7 +120,7 @@ if (i > 0) printf(" "); if (stack_symbol(st->pcs[i], namebuf, sizeof(namebuf), - &offset) == 0) + &offset, M_WAITOK) == 0) printf("%s+%#lx", namebuf, offset); else printf("%p", (void *)st->pcs[i]); @@ -165,25 +165,36 @@ #endif /* - * Two print routines -- one for use from DDB and DDB-like contexts, the - * other for use in the live kernel. + * Format stack into sbuf from live kernel. + * + * flags - M_WAITOK or M_NOWAIT (EWOULDBLOCK). */ -void -stack_sbuf_print(struct sbuf *sb, const struct stack *st) +int +stack_sbuf_print_flags(struct sbuf *sb, const struct stack *st, int flags) { char namebuf[64]; long offset; - int i; + int i, error; KASSERT(st->depth <= STACK_MAX, ("bogus stack")); for (i = 0; i < st->depth; i++) { - (void)stack_symbol(st->pcs[i], namebuf, sizeof(namebuf), - &offset); + error = stack_symbol(st->pcs[i], namebuf, sizeof(namebuf), + &offset, flags); + if (error == EWOULDBLOCK) + return (error); sbuf_printf(sb, "#%d %p at %s+%#lx\n", i, (void *)st->pcs[i], namebuf, offset); } + return (0); } +void +stack_sbuf_print(struct sbuf *sb, const struct stack *st) +{ + + (void)stack_sbuf_print_flags(sb, st, M_WAITOK); +} + #if defined(DDB) || defined(WITNESS) void stack_sbuf_print_ddb(struct sbuf *sb, const struct stack *st) @@ -246,16 +257,19 @@ * and bypasses linker locking, and the other that doesn't. */ static int -stack_symbol(vm_offset_t pc, char *namebuf, u_int buflen, long *offset) +stack_symbol(vm_offset_t pc, char *namebuf, u_int buflen, long *offset, + int flags) { + int error; - if (linker_search_symbol_name((caddr_t)pc, namebuf, buflen, - offset) != 0) { - *offset = 0; - strlcpy(namebuf, "??", buflen); - return (ENOENT); - } else - return (0); + error = linker_search_symbol_name_flags((caddr_t)pc, namebuf, buflen, + offset, flags); + if (error == 0 || error == EWOULDBLOCK) + return (error); + + *offset = 0; + strlcpy(namebuf, "??", buflen); + return (ENOENT); } static int Index: head/sys/sys/linker.h =================================================================== --- head/sys/sys/linker.h +++ head/sys/sys/linker.h @@ -183,6 +183,8 @@ /* * stack(9) helper for situations where kernel locking is required. */ +int linker_search_symbol_name_flags(caddr_t value, char *buf, u_int buflen, + long *offset, int flags); int linker_search_symbol_name(caddr_t value, char *buf, u_int buflen, long *offset); Index: head/sys/sys/stack.h =================================================================== --- head/sys/sys/stack.h +++ head/sys/sys/stack.h @@ -47,6 +47,8 @@ void stack_print_short_ddb(const struct stack *); void stack_sbuf_print(struct sbuf *, const struct stack *); void stack_sbuf_print_ddb(struct sbuf *, const struct stack *); +int stack_sbuf_print_flags(struct sbuf *, const struct stack *, + int); #ifdef KTR void stack_ktr(u_int, const char *, int, const struct stack *, u_int, int);