diff options
author | rwatson <rwatson@FreeBSD.org> | 2007-12-02 20:40:35 +0000 |
---|---|---|
committer | rwatson <rwatson@FreeBSD.org> | 2007-12-02 20:40:35 +0000 |
commit | 99285f7544399971d1bcb6e3c18e7010905925e5 (patch) | |
tree | 25f0781d4e40520309936f686c0accc99753b656 /sys/sparc64 | |
parent | e6e32be1d57fbe0f67adfd9c0cb818a1660dca5a (diff) | |
download | FreeBSD-src-99285f7544399971d1bcb6e3c18e7010905925e5.zip FreeBSD-src-99285f7544399971d1bcb6e3c18e7010905925e5.tar.gz |
Break out stack(9) from ddb(4):
- Introduce per-architecture stack_machdep.c to hold stack_save(9).
- Introduce per-architecture machine/stack.h to capture any common
definitions required between db_trace.c and stack_machdep.c.
- Add new kernel option "options STACK"; we will build in stack(9) if it is
defined, or also if "options DDB" is defined to provide compatibility
with existing users of stack(9).
Add new stack_save_td(9) function, which allows the capture of a stacktrace
of another thread rather than the current thread, which the existing
stack_save(9) was limited to. It requires that the thread be neither
swapped out nor running, which is the responsibility of the consumer to
enforce.
Update stack(9) man page.
Build tested: amd64, arm, i386, ia64, powerpc, sparc64, sun4v
Runtime tested: amd64 (rwatson), arm (cognet), i386 (rwatson)
Diffstat (limited to 'sys/sparc64')
-rw-r--r-- | sys/sparc64/conf/GENERIC | 1 | ||||
-rw-r--r-- | sys/sparc64/include/stack.h | 40 | ||||
-rw-r--r-- | sys/sparc64/sparc64/db_trace.c | 35 | ||||
-rw-r--r-- | sys/sparc64/sparc64/stack_machdep.c | 90 |
4 files changed, 132 insertions, 34 deletions
diff --git a/sys/sparc64/conf/GENERIC b/sys/sparc64/conf/GENERIC index 29df474..a3435f7 100644 --- a/sys/sparc64/conf/GENERIC +++ b/sys/sparc64/conf/GENERIC @@ -56,6 +56,7 @@ options COMPAT_FREEBSD5 # Compatible with FreeBSD5 options COMPAT_FREEBSD6 # Compatible with FreeBSD6 options SCSI_DELAY=5000 # Delay (in ms) before probing SCSI options KTRACE # ktrace(1) support +options STACK # stack(9) support options SYSVSHM # SYSV-style shared memory options SYSVMSG # SYSV-style message queues options SYSVSEM # SYSV-style semaphores diff --git a/sys/sparc64/include/stack.h b/sys/sparc64/include/stack.h new file mode 100644 index 0000000..14ed721 --- /dev/null +++ b/sys/sparc64/include/stack.h @@ -0,0 +1,40 @@ +/*- + * Copyright (c) 2001 Jake Burkholder. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _MACHINE_STACK_H_ +#define _MACHINE_STACK_H_ + +extern char tl_trap_begin[]; +extern char tl_trap_end[]; +extern char tl_text_begin[]; +extern char tl_text_end[]; + +#define INKERNEL(va) \ + ((va) >= VM_MIN_KERNEL_ADDRESS && (va) <= VM_MAX_KERNEL_ADDRESS) + +#endif /* !_MACHINE_STACK_H_ */ diff --git a/sys/sparc64/sparc64/db_trace.c b/sys/sparc64/sparc64/db_trace.c index 73d3b31..7a30664 100644 --- a/sys/sparc64/sparc64/db_trace.c +++ b/sys/sparc64/sparc64/db_trace.c @@ -41,6 +41,7 @@ __FBSDID("$FreeBSD$"); #include <machine/cpu.h> #include <machine/pcb.h> +#include <machine/stack.h> #include <machine/trap.h> #include <machine/vmparam.h> @@ -50,14 +51,6 @@ __FBSDID("$FreeBSD$"); #include <ddb/db_variables.h> #include <ddb/db_watch.h> -extern char tl_trap_begin[]; -extern char tl_trap_end[]; -extern char tl_text_begin[]; -extern char tl_text_end[]; - -#define INKERNEL(va) \ - ((va) >= VM_MIN_KERNEL_ADDRESS && (va) <= VM_MAX_KERNEL_ADDRESS) - static db_varfcn_t db_frame; #define DB_OFFSET(x) (db_expr_t *)offsetof(struct trapframe, x) @@ -297,29 +290,3 @@ db_trace_thread(struct thread *td, int count) ctx = kdb_thr_ctx(td); return (db_backtrace(td, (struct frame*)(ctx->pcb_sp + SPOFF), count)); } - -void -stack_save(struct stack *st) -{ - struct frame *fp; - db_expr_t addr; - vm_offset_t callpc; - - stack_zero(st); - addr = (db_expr_t)__builtin_frame_address(1); - fp = (struct frame *)(addr + SPOFF); - while (1) { - callpc = fp->fr_pc; - if (!INKERNEL(callpc)) - break; - /* Don't bother traversing trap frames. */ - if ((callpc > (u_long)tl_trap_begin && - callpc < (u_long)tl_trap_end) || - (callpc > (u_long)tl_text_begin && - callpc < (u_long)tl_text_end)) - break; - if (stack_put(st, callpc) == -1) - break; - fp = (struct frame *)(fp->fr_fp + SPOFF); - } -} diff --git a/sys/sparc64/sparc64/stack_machdep.c b/sys/sparc64/sparc64/stack_machdep.c new file mode 100644 index 0000000..bfaf248 --- /dev/null +++ b/sys/sparc64/sparc64/stack_machdep.c @@ -0,0 +1,90 @@ +/*- + * Copyright (c) 2005 Antoine Brodin + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> +#include <sys/proc.h> +#include <sys/stack.h> +#include <sys/systm.h> + +#include <vm/vm.h> +#include <vm/vm_page.h> +#include <vm/vm_map.h> + +#include <machine/cpu.h> +#include <machine/pcb.h> +#include <machine/stack.h> +#include <machine/trap.h> +#include <machine/vmparam.h> + +static void +stack_capture(struct stack *st, uint64_t addr) +{ + struct frame *fp; + vm_offset_t callpc; + + stack_zero(st); + fp = (struct frame *)(addr + SPOFF); + while (1) { + callpc = fp->fr_pc; + if (!INKERNEL(callpc)) + break; + /* Don't bother traversing trap frames. */ + if ((callpc > (uint64_t)tl_trap_begin && + callpc < (uint64_t)tl_trap_end) || + (callpc > (uint64_t)tl_text_begin && + callpc < (uint64_t)tl_text_end)) + break; + if (stack_put(st, callpc) == -1) + break; + fp = (struct frame *)(fp->fr_fp + SPOFF); + } +} + +void +stack_save_td(struct stack *st, struct thread *td) +{ + uint64_t addr; + + if (TD_IS_SWAPPED(td)) + panic("stack_save_td: swapped"); + if (TD_IS_RUNNING(td)) + panic("stack_save_td: running"); + + addr = td->td_pcb->pcb_sp; + stack_capture(st, addr); +} + +void +stack_save(struct stack *st) +{ + uint64_t addr; + + addr = (uint64_t)__builtin_frame_address(1); + stack_capture(st, addr); +} |