Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 24 Jun 2009 12:06:15 +0000 (UTC)
From:      Robert Watson <rwatson@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r194828 - in head: share/man/man9 sys/kern sys/sys
Message-ID:  <200906241206.n5OC6FpT013646@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: rwatson
Date: Wed Jun 24 12:06:15 2009
New Revision: 194828
URL: http://svn.freebsd.org/changeset/base/194828

Log:
  Add stack_print_short() and stack_print_short_ddb() interfaces to
  stack(9), which generate a more compact rendition of a stack trace
  via the kernel's printf.
  
  MFC after:	1 week

Modified:
  head/share/man/man9/stack.9
  head/sys/kern/subr_stack.c
  head/sys/sys/stack.h

Modified: head/share/man/man9/stack.9
==============================================================================
--- head/share/man/man9/stack.9	Wed Jun 24 12:04:26 2009	(r194827)
+++ head/share/man/man9/stack.9	Wed Jun 24 12:06:15 2009	(r194828)
@@ -1,5 +1,5 @@
 .\"
-.\" Copyright (c) 2007 Robert N. M. Watson
+.\" Copyright (c) 2007-2009 Robert N. M. Watson
 .\" All rights reserved.
 .\"
 .\" Redistribution and use in source and binary forms, with or without
@@ -27,7 +27,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd February 27, 2007
+.Dd June 24, 2009
 .Dt STACK 9
 .Os
 .Sh NAME
@@ -54,6 +54,10 @@ In the kernel configuration file:
 .Ft void
 .Fn stack_print_ddb "struct stack *st"
 .Ft void
+.Fn stack_print_short "struct stack *st"
+.Ft void
+.Fn stack_print_short_ddb "struct stack *st"
+.Ft void
 .Fn stack_sbuf_print "struct sbuf sb*" "struct stack *st"
 .Ft void
 .Fn stack_sbuf_print_ddb "struct sbuf sb*" "struct stack *st"
@@ -84,6 +88,8 @@ A trace of the current kernel thread's c
 .Fn stack_save .
 .Pp
 .Fn stack_print
+and
+.Fn stack_print_short
 may be used to print a stack trace using the kernel
 .Xr printf 9 ,
 and may sleep as a result of acquiring
@@ -91,7 +97,9 @@ and may sleep as a result of acquiring
 locks in the kernel linker while looking up symbol names.
 In locking-sensitive environments, the unsynchronized
 .Fn stack_print_ddb
-variant may be invoked.
+and
+.Fn stack_print_short_ddb
+variants may be invoked.
 This function bypasses kernel linker locking, making it usable in
 .Xr ddb 4 ,
 but not in a live system where linker data structures may change.

Modified: head/sys/kern/subr_stack.c
==============================================================================
--- head/sys/kern/subr_stack.c	Wed Jun 24 12:04:26 2009	(r194827)
+++ head/sys/kern/subr_stack.c	Wed Jun 24 12:06:15 2009	(r194828)
@@ -42,10 +42,10 @@ __FBSDID("$FreeBSD$");
 
 static MALLOC_DEFINE(M_STACK, "stack", "Stack Traces");
 
-static void stack_symbol(vm_offset_t pc, char *namebuf, u_int buflen,
+static int stack_symbol(vm_offset_t pc, char *namebuf, u_int buflen,
 	    long *offset);
 #ifdef DDB
-static void stack_symbol_ddb(vm_offset_t pc, const char **name, long *offset);
+static int stack_symbol_ddb(vm_offset_t pc, const char **name, long *offset);
 #endif
 
 struct stack *
@@ -98,12 +98,33 @@ stack_print(struct stack *st)
 
 	KASSERT(st->depth <= STACK_MAX, ("bogus stack"));
 	for (i = 0; i < st->depth; i++) {
-		stack_symbol(st->pcs[i], namebuf, sizeof(namebuf), &offset);
+		(void)stack_symbol(st->pcs[i], namebuf, sizeof(namebuf),
+		    &offset);
 		printf("#%d %p at %s+%#lx\n", i, (void *)st->pcs[i],
 		    namebuf, offset);
 	}
 }
 
+void
+stack_print_short(struct stack *st)
+{
+	char namebuf[64];
+	long offset;
+	int i;
+
+	KASSERT(st->depth <= STACK_MAX, ("bogus stack"));
+	for (i = 0; i < st->depth; i++) {
+		if (i > 0)
+			printf(" ");
+		if (stack_symbol(st->pcs[i], namebuf, sizeof(namebuf),
+		    &offset) == 0)
+			printf("%s+%#lx", namebuf, offset);
+		else
+			printf("%p", (void *)st->pcs[i]);
+	}
+	printf("\n");
+}
+
 #ifdef DDB
 void
 stack_print_ddb(struct stack *st)
@@ -119,6 +140,25 @@ stack_print_ddb(struct stack *st)
 		    name, offset);
 	}
 }
+
+void
+stack_print_short_ddb(struct stack *st)
+{
+	const char *name;
+	long offset;
+	int i;
+
+	KASSERT(st->depth <= STACK_MAX, ("bogus stack"));
+	for (i = 0; i < st->depth; i++) {
+		if (i > 0)
+			printf(" ");
+		if (stack_symbol_ddb(st->pcs[i], &name, &offset) == 0)
+			printf("%s+%#lx", name, offset);
+		else
+			printf("%p", (void *)st->pcs[i]);
+	}
+	printf("\n");
+}
 #endif
 
 /*
@@ -134,7 +174,8 @@ stack_sbuf_print(struct sbuf *sb, struct
 
 	KASSERT(st->depth <= STACK_MAX, ("bogus stack"));
 	for (i = 0; i < st->depth; i++) {
-		stack_symbol(st->pcs[i], namebuf, sizeof(namebuf), &offset);
+		(void)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);
 	}
@@ -150,7 +191,7 @@ stack_sbuf_print_ddb(struct sbuf *sb, st
 
 	KASSERT(st->depth <= STACK_MAX, ("bogus stack"));
 	for (i = 0; i < st->depth; i++) {
-		stack_symbol_ddb(st->pcs[i], &name, &offset);
+		(void)stack_symbol_ddb(st->pcs[i], &name, &offset);
 		sbuf_printf(sb, "#%d %p at %s+%#lx\n", i, (void *)st->pcs[i],
 		    name, offset);
 	}
@@ -188,7 +229,7 @@ stack_ktr(u_int mask, const char *file, 
 		if (depth == 0 || st->depth < depth)
 			depth = st->depth;
 		for (i = 0; i < depth; i++) {
-			stack_symbol_ddb(st->pcs[i], &name, &offset);
+			(void)stack_symbol_ddb(st->pcs[i], &name, &offset);
 			ktr_tracepoint(mask, file, line, "#%d %p at %s+%#lx",
 			    i, st->pcs[i], (u_long)name, offset, 0, 0);
 		}
@@ -201,7 +242,7 @@ stack_ktr(u_int mask, const char *file, 
  * Two variants of stack symbol lookup -- one that uses the DDB interfaces
  * and bypasses linker locking, and the other that doesn't.
  */
-static void
+static int
 stack_symbol(vm_offset_t pc, char *namebuf, u_int buflen, long *offset)
 {
 
@@ -209,11 +250,13 @@ stack_symbol(vm_offset_t pc, char *nameb
 	    offset) != 0) {
 		*offset = 0;
 		strlcpy(namebuf, "??", buflen);
-	}
+		return (ENOENT);
+	} else
+		return (0);
 }
 
 #ifdef DDB
-static void
+static int
 stack_symbol_ddb(vm_offset_t pc, const char **name, long *offset)
 {
 	linker_symval_t symval;
@@ -225,10 +268,11 @@ stack_symbol_ddb(vm_offset_t pc, const c
 		goto out;
 	if (symval.name != NULL) {
 		*name = symval.name;
-		return;
+		return (0);
 	}
  out:
 	*offset = 0;
 	*name = "??";
+	return (ENOENT);
 }
 #endif

Modified: head/sys/sys/stack.h
==============================================================================
--- head/sys/sys/stack.h	Wed Jun 24 12:04:26 2009	(r194827)
+++ head/sys/sys/stack.h	Wed Jun 24 12:06:15 2009	(r194828)
@@ -41,6 +41,8 @@ void		 stack_copy(struct stack *, struct
 void		 stack_zero(struct stack *);
 void		 stack_print(struct stack *);
 void		 stack_print_ddb(struct stack *);
+void		 stack_print_short(struct stack *);
+void		 stack_print_short_ddb(struct stack *);
 void		 stack_sbuf_print(struct sbuf *, struct stack *);
 void		 stack_sbuf_print_ddb(struct sbuf *, struct stack *);
 #ifdef KTR



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200906241206.n5OC6FpT013646>