From owner-svn-src-head@FreeBSD.ORG Wed Jun 24 12:06:16 2009 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 287D2106568F; Wed, 24 Jun 2009 12:06:16 +0000 (UTC) (envelope-from rwatson@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 020698FC17; Wed, 24 Jun 2009 12:06:16 +0000 (UTC) (envelope-from rwatson@FreeBSD.org) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id n5OC6FAt013650; Wed, 24 Jun 2009 12:06:15 GMT (envelope-from rwatson@svn.freebsd.org) Received: (from rwatson@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id n5OC6FpT013646; Wed, 24 Jun 2009 12:06:15 GMT (envelope-from rwatson@svn.freebsd.org) Message-Id: <200906241206.n5OC6FpT013646@svn.freebsd.org> From: Robert Watson Date: Wed, 24 Jun 2009 12:06:15 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r194828 - in head: share/man/man9 sys/kern sys/sys X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 24 Jun 2009 12:06:24 -0000 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