summaryrefslogtreecommitdiffstats
path: root/sys/kern/subr_stack.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/kern/subr_stack.c')
-rw-r--r--sys/kern/subr_stack.c103
1 files changed, 79 insertions, 24 deletions
diff --git a/sys/kern/subr_stack.c b/sys/kern/subr_stack.c
index 705c21b..e3cf156 100644
--- a/sys/kern/subr_stack.c
+++ b/sys/kern/subr_stack.c
@@ -24,6 +24,8 @@
* SUCH DAMAGE.
*/
+#include "opt_ddb.h"
+
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
@@ -40,7 +42,12 @@ __FBSDID("$FreeBSD$");
MALLOC_DEFINE(M_STACK, "stack", "Stack Traces");
-static void stack_symbol(vm_offset_t pc, const char **name, long *offset);
+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);
+#endif
struct stack *
stack_create(void)
@@ -86,30 +93,67 @@ stack_zero(struct stack *st)
void
stack_print(struct stack *st)
{
- const char *name;
+ char namebuf[64];
long offset;
int i;
KASSERT(st->depth <= STACK_MAX, ("bogus stack"));
for (i = 0; i < st->depth; i++) {
- stack_symbol(st->pcs[i], &name, &offset);
+ stack_symbol(st->pcs[i], namebuf, sizeof(namebuf), &offset);
printf("#%d %p at %s+%#lx\n", i, (void *)st->pcs[i],
- name, offset);
+ namebuf, offset);
}
}
void
+stack_print_ddb(struct stack *st)
+{
+ char namebuf[64];
+ 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);
+ printf("#%d %p at %s+%#lx\n", i, (void *)st->pcs[i],
+ namebuf, offset);
+ }
+}
+
+/*
+ * Two print routines -- one for use from DDB and DDB-like contexts, the
+ * other for use in the live kernel.
+ */
+void
stack_sbuf_print(struct sbuf *sb, struct stack *st)
{
- const char *name;
+ char namebuf[64];
+ long offset;
+ int i;
+
+ KASSERT(st->depth <= STACK_MAX, ("bogus stack"));
+ for (i = 0; i < st->depth; i++) {
+ stack_symbol(st->pcs[i], namebuf, sizeof(namebuf), &offset);
+ sbuf_printf(sb, "#%d %p at %s+%#lx\n", i, (void *)st->pcs[i],
+ namebuf, offset);
+ }
+}
+
+#ifdef DDB
+void
+stack_sbuf_print_ddb(struct sbuf *sb, struct stack *st)
+{
+ char namebuf[64];
long offset;
int i;
KASSERT(st->depth <= STACK_MAX, ("bogus stack"));
for (i = 0; i < st->depth; i++) {
- stack_symbol(st->pcs[i], &name, &offset);
+ stack_symbol_ddb(st->pcs[i], namebuf, sizeof(namebuf),
+ &offset);
sbuf_printf(sb, "#%d %p at %s+%#lx\n", i, (void *)st->pcs[i],
- name, offset);
+ namebuf, offset);
}
}
@@ -118,7 +162,7 @@ void
stack_ktr(u_int mask, const char *file, int line, struct stack *st, u_int depth,
int cheap)
{
- const char *name;
+ char namebuf[64];
long offset;
int i;
@@ -141,29 +185,40 @@ 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(st->pcs[i], &name, &offset);
+ stack_symbol_ddb(st->pcs[i], namebuf,
+ sizeof(namebuf), &offset);
ktr_tracepoint(mask, file, line, "#%d %p at %s+%#lx",
- i, st->pcs[i], (u_long)name, offset, 0, 0);
+ i, st->pcs[i], (u_long)namebuf, offset, 0, 0);
}
}
}
#endif
+#endif
+/*
+ * Two variants of stack symbol lookup -- one that uses the DDB interfaces
+ * and bypasses linker locking, and the other that doesn't.
+ */
static void
-stack_symbol(vm_offset_t pc, const char **name, long *offset)
+stack_symbol(vm_offset_t pc, char *namebuf, u_int buflen, long *offset)
{
- 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;
+
+ if (linker_search_symbol_name((caddr_t)pc, namebuf, buflen,
+ offset) != 0) {
+ *offset = 0;
+ strlcpy(namebuf, "Unknown func", buflen);
}
-out:
- *offset = 0;
- *name = "Unknown func";
}
+
+#ifdef DDB
+static void
+stack_symbol_ddb(vm_offset_t pc, char *namebuf, u_int buflen, long *offset)
+{
+
+ if (linker_ddb_search_symbol_name((caddr_t)pc, namebuf, buflen,
+ offset) != 0) {
+ *offset = 0;
+ strlcpy(namebuf, "Unknown func", buflen);
+ };
+}
+#endif
OpenPOWER on IntegriCloud