diff options
40 files changed, 883 insertions, 232 deletions
diff --git a/share/man/man9/stack.9 b/share/man/man9/stack.9 index 17cf509..d71af96 100644 --- a/share/man/man9/stack.9 +++ b/share/man/man9/stack.9 @@ -36,9 +36,9 @@ .Sh SYNOPSIS .In sys/param.h> .In sys/stack.h -.Pp -In kernel configuration files: +In the kernel configuration file: .Cd "options DDB" +.Cd "options STACK" .Ft struct stack * .Fn stack_create "void" .Ft void @@ -63,12 +63,11 @@ The KPI allows querying of kernel stack trace information and the automated generation of kernel stack trace strings for the purposes of debugging and tracing. -.Nm -relies on the presence of -.Xr DDB 4 , -and all use of these functions must be made conditional on -.Nm DDB -being compiled in the kernel. +To use the KPI, at least one of +.Cd "options DDB" +and +.Cd "options STACK" +must be compiled into the kernel. .Pp Each stack trace is described by a .Vt "struct stack" . @@ -76,7 +75,7 @@ Before a trace may be created or otherwise manipulated, storage for the trace must be allocated with .Fn stack_create , which may sleep. -Memory associated with a trace may be freed by calling +Memory associated with a trace is freed by calling .Fn stack_destroy . .Pp A trace of the current kernel thread's call stack may be captured using @@ -84,7 +83,16 @@ A trace of the current kernel thread's call stack may be captured using .Pp .Fn stack_print may be used to print a stack trace using the kernel -.Xr printf 9 . +.Xr printf 9 , +and may sleep as a result of acquiring +.Xr sx 9 +locks in the kernel linker while looking up symbol names. +In locking-sensitive environments, the unsynchronized +.Fn stack_print_ddb +variant 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. .Pp .Fn stack_sbuf_print may be used to construct a human-readable string, including conversion (where @@ -98,17 +106,13 @@ as described in .Xr sbuf 9 . This function may sleep if an auto-extending .Dv struct sbuf -is used, and because the kernel linker (used to look up symbol names) uses -.Xr sx 9 -locks. -.Pp +is used, or due to kernel linker locking. In locking-sensitive environments, such as -.Xr DDB 4 , +.Xr ddb 4 , the unsynchronized .Fn stack_sbuf_print_ddb -variant may be invoked; this makes use of kernel linker data structures to -look up symbol names without following locking protocols, so is appropriate -for use in the debugger but not while the system is live. +variant may be invoked to avoid kernel linker locking; it should be used with +a fixed-length sbuf. .Pp The utility functions .Nm stack_zero , @@ -117,7 +121,7 @@ and .Nm stack_put may be used to manipulate stack data structures directly. .Sh SEE ALSO -.Xr DDB 4 , +.Xr ddb 4 , .Xr printf 9 , .Xr sbuf 9 , .Xr sx 9 @@ -127,6 +131,8 @@ The .Xr stack 9 function suite was created by .An Antoine Brodin . -.Pp -This manual page was written by -.An Robert Watson . +.Xr stack 9 +was extended by +.An Robert Watson +for general-purpose use outside of +.Xr ddb 4 . diff --git a/sys/amd64/amd64/db_trace.c b/sys/amd64/amd64/db_trace.c index 548c36c..c4e552d 100644 --- a/sys/amd64/amd64/db_trace.c +++ b/sys/amd64/amd64/db_trace.c @@ -38,6 +38,7 @@ __FBSDID("$FreeBSD$"); #include <machine/md_var.h> #include <machine/pcb.h> #include <machine/reg.h> +#include <machine/stack.h> #include <vm/vm.h> #include <vm/vm_param.h> @@ -177,18 +178,6 @@ db_ss(struct db_variable *vp, db_expr_t *valuep, int op) return (1); } -/* - * Stack trace. - */ -#define INKERNEL(va) (((va) >= DMAP_MIN_ADDRESS && (va) < DMAP_MAX_ADDRESS) \ - || ((va) >= KERNBASE && (va) < VM_MAX_KERNEL_ADDRESS)) - -struct amd64_frame { - struct amd64_frame *f_frame; - long f_retaddr; - long f_arg0; -}; - #define NORMAL 0 #define TRAP 1 #define INTERRUPT 2 @@ -505,32 +494,6 @@ db_trace_thread(struct thread *thr, int count) ctx->pcb_rip, count)); } -void -stack_save(struct stack *st) -{ - struct amd64_frame *frame; - vm_offset_t callpc; - register_t rbp; - - stack_zero(st); - __asm __volatile("movq %%rbp,%0" : "=r" (rbp)); - frame = (struct amd64_frame *)rbp; - while (1) { - if (!INKERNEL((long)frame)) - break; - callpc = frame->f_retaddr; - if (!INKERNEL(callpc)) - break; - if (stack_put(st, callpc) == -1) - break; - if (frame->f_frame <= frame || - (vm_offset_t)frame->f_frame >= - (vm_offset_t)rbp + KSTACK_PAGES * PAGE_SIZE) - break; - frame = frame->f_frame; - } -} - int amd64_set_watch(watchnum, watchaddr, size, access, d) int watchnum; diff --git a/sys/amd64/amd64/stack_machdep.c b/sys/amd64/amd64/stack_machdep.c new file mode 100644 index 0000000..57908e2 --- /dev/null +++ b/sys/amd64/amd64/stack_machdep.c @@ -0,0 +1,87 @@ +/*- + * 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/systm.h> +#include <sys/proc.h> +#include <sys/stack.h> + +#include <machine/pcb.h> +#include <machine/stack.h> + +#include <vm/vm.h> +#include <vm/vm_param.h> +#include <vm/pmap.h> + +static void +stack_capture(struct stack *st, register_t rbp) +{ + struct amd64_frame *frame; + vm_offset_t callpc; + + stack_zero(st); + frame = (struct amd64_frame *)rbp; + while (1) { + if (!INKERNEL((long)frame)) + break; + callpc = frame->f_retaddr; + if (!INKERNEL(callpc)) + break; + if (stack_put(st, callpc) == -1) + break; + if (frame->f_frame <= frame || + (vm_offset_t)frame->f_frame >= + (vm_offset_t)rbp + KSTACK_PAGES * PAGE_SIZE) + break; + frame = frame->f_frame; + } +} + +void +stack_save_td(struct stack *st, struct thread *td) +{ + register_t rbp; + + if (TD_IS_SWAPPED(td)) + panic("stack_save_td: swapped"); + if (TD_IS_RUNNING(td)) + panic("stack_save_td: running"); + + rbp = td->td_pcb->pcb_rbp; + stack_capture(st, rbp); +} + +void +stack_save(struct stack *st) +{ + register_t rbp; + + __asm __volatile("movq %%rbp,%0" : "=r" (rbp)); + stack_capture(st, rbp); +} diff --git a/sys/amd64/conf/GENERIC b/sys/amd64/conf/GENERIC index a809f8e..3786bba 100644 --- a/sys/amd64/conf/GENERIC +++ b/sys/amd64/conf/GENERIC @@ -54,6 +54,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/amd64/include/stack.h b/sys/amd64/include/stack.h new file mode 100644 index 0000000..2a70d30 --- /dev/null +++ b/sys/amd64/include/stack.h @@ -0,0 +1,44 @@ +/*- + * Mach Operating System + * Copyright (c) 1991,1990 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie the + * rights to redistribute these changes. + * + * $FreeBSD$ + */ + +#ifndef _MACHINE_STACK_H_ +#define _MACHINE_STACK_H_ + +/* + * Stack trace. + */ +#define INKERNEL(va) (((va) >= DMAP_MIN_ADDRESS && (va) < DMAP_MAX_ADDRESS) \ + || ((va) >= KERNBASE && (va) < VM_MAX_KERNEL_ADDRESS)) + +struct amd64_frame { + struct amd64_frame *f_frame; + long f_retaddr; + long f_arg0; +}; + +#endif /* !_MACHINE_STACK_H_ */ diff --git a/sys/arm/arm/db_trace.c b/sys/arm/arm/db_trace.c index e9ce328..6913df6 100644 --- a/sys/arm/arm/db_trace.c +++ b/sys/arm/arm/db_trace.c @@ -43,14 +43,13 @@ __FBSDID("$FreeBSD$"); #include <machine/cpufunc.h> #include <machine/db_machdep.h> #include <machine/pcb.h> +#include <machine/stack.h> #include <machine/vmparam.h> #include <ddb/ddb.h> #include <ddb/db_access.h> #include <ddb/db_sym.h> #include <ddb/db_output.h> -#define INKERNEL(va) (((vm_offset_t)(va)) >= VM_MIN_KERNEL_ADDRESS) - /* * APCS stack frames are awkward beasts, so I don't think even trying to use * a structure to represent them is a good idea. @@ -79,11 +78,6 @@ __FBSDID("$FreeBSD$"); * fields are actually present. */ -#define FR_SCP (0) -#define FR_RLV (-1) -#define FR_RSP (-2) -#define FR_RFP (-3) - static void db_stack_trace_cmd(db_expr_t addr, db_expr_t count) { @@ -215,21 +209,3 @@ db_trace_self(void) { db_trace_thread(curthread, -1); } - -void -stack_save(struct stack *st) -{ - vm_offset_t callpc; - u_int32_t *frame; - - stack_zero(st); - frame = (u_int32_t *)__builtin_frame_address(0); - while (1) { - if (!INKERNEL(frame)) - break; - callpc = frame[FR_SCP]; - if (stack_put(st, callpc) == -1) - break; - frame = (u_int32_t *)(frame[FR_RFP]); - } -} diff --git a/sys/arm/arm/stack_machdep.c b/sys/arm/arm/stack_machdep.c new file mode 100644 index 0000000..a6032bc --- /dev/null +++ b/sys/arm/arm/stack_machdep.c @@ -0,0 +1,76 @@ +/*- + * 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/systm.h> +#include <sys/param.h> +#include <sys/proc.h> +#include <sys/stack.h> + +#include <machine/vmparam.h> +#include <machine/pcb.h> +#include <machine/stack.h> + +static void +stack_capture(struct stack *st, u_int32_t *frame) +{ + vm_offset_t callpc; + + stack_zero(st); + while (1) { + if (!INKERNEL(frame)) + break; + callpc = frame[FR_SCP]; + if (stack_put(st, callpc) == -1) + break; + frame = (u_int32_t *)(frame[FR_RFP]); + } +} + +void +stack_save_td(struct stack *st, struct thread *td) +{ + u_int32_t *frame; + + if (TD_IS_SWAPPED(td)) + panic("stack_save_td: swapped"); + if (TD_IS_RUNNING(td)) + panic("stack_save_td: running"); + + frame = (u_int32_t *)td->td_pcb->un_32.pcb32_r11; + stack_capture(st, frame); +} + +void +stack_save(struct stack *st) +{ + u_int32_t *frame; + + frame = (u_int32_t *)__builtin_frame_address(0); + stack_capture(st, frame); +} diff --git a/sys/arm/include/stack.h b/sys/arm/include/stack.h new file mode 100644 index 0000000..32ff5a9 --- /dev/null +++ b/sys/arm/include/stack.h @@ -0,0 +1,42 @@ +/*- + * Copyright (c) 2000, 2001 Ben Harris + * Copyright (c) 1996 Scott K. Stevens + * + * Mach Operating System + * Copyright (c) 1991,1990 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie the + * rights to redistribute these changes. + * + * $FreeBSD$ + */ + +#ifndef _MACHINE_STACK_H_ +#define _MACHINE_STACK_H_ + +#define INKERNEL(va) (((vm_offset_t)(va)) >= VM_MIN_KERNEL_ADDRESS) + +#define FR_SCP (0) +#define FR_RLV (-1) +#define FR_RSP (-2) +#define FR_RFP (-3) + +#endif /* !_MACHINE_STACK_H_ */ diff --git a/sys/conf/NOTES b/sys/conf/NOTES index 2f62598..eb66fa7 100644 --- a/sys/conf/NOTES +++ b/sys/conf/NOTES @@ -465,6 +465,13 @@ options REGRESSION # options COMPILING_LINT +# +# STACK enables the stack(9) facility, allowing the capture of kernel stack +# for the purpose of procinfo(1), etc. stack(9) will also be compiled in +# automatically if DDB(4) is compiled into the kernel. +# +options STACK + ##################################################################### # PERFORMANCE MONITORING OPTIONS diff --git a/sys/conf/files b/sys/conf/files index ff4d8f2..a0a796d 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -1504,7 +1504,7 @@ kern/subr_sbuf.c standard kern/subr_scanf.c standard kern/subr_sleepqueue.c standard kern/subr_smp.c standard -kern/subr_stack.c optional ddb +kern/subr_stack.c optional ddb | stack kern/subr_taskqueue.c standard kern/subr_trap.c standard kern/subr_turnstile.c standard diff --git a/sys/conf/files.amd64 b/sys/conf/files.amd64 index dbe920d..8276f85 100644 --- a/sys/conf/files.amd64 +++ b/sys/conf/files.amd64 @@ -119,6 +119,7 @@ amd64/amd64/nexus.c standard amd64/amd64/pmap.c standard nowerror amd64/amd64/prof_machdep.c optional profiling-routine amd64/amd64/sigtramp.S standard +amd64/amd64/stack_machdep.c optional ddb | stack amd64/amd64/support.S standard amd64/amd64/sys_machdep.c standard amd64/amd64/trap.c standard diff --git a/sys/conf/files.arm b/sys/conf/files.arm index 42eb602..3cb7a5c 100644 --- a/sys/conf/files.arm +++ b/sys/conf/files.arm @@ -34,6 +34,7 @@ arm/arm/nexus.c standard arm/arm/pmap.c standard arm/arm/setcpsr.S standard arm/arm/setstack.s standard +arm/arm/stack_machdep.c optional ddb | stack arm/arm/support.S standard arm/arm/swtch.S standard arm/arm/sys_machdep.c standard diff --git a/sys/conf/files.i386 b/sys/conf/files.i386 index 1ddcb4c..9e43eca 100644 --- a/sys/conf/files.i386 +++ b/sys/conf/files.i386 @@ -308,6 +308,7 @@ i386/i386/nexus.c standard i386/i386/perfmon.c optional perfmon i386/i386/pmap.c standard nowerror i386/i386/ptrace_machdep.c standard +i386/i386/stack_machdep.c optional ddb | stack i386/i386/support.s standard i386/i386/swtch.s standard i386/i386/sys_machdep.c standard diff --git a/sys/conf/files.ia64 b/sys/conf/files.ia64 index f2f5b36..3824fe4 100644 --- a/sys/conf/files.ia64 +++ b/sys/conf/files.ia64 @@ -98,6 +98,7 @@ ia64/ia64/sapic.c standard ia64/ia64/setjmp.S standard ia64/ia64/ssc.c optional ski ia64/ia64/sscdisk.c optional ski +ia64/ia64/stack_machdep.c optional ddb | stack ia64/ia64/support.S standard ia64/ia64/sys_machdep.c standard ia64/ia64/syscall.S standard diff --git a/sys/conf/files.powerpc b/sys/conf/files.powerpc index fc72f32..3e85464 100644 --- a/sys/conf/files.powerpc +++ b/sys/conf/files.powerpc @@ -61,6 +61,7 @@ powerpc/powerpc/pmap_dispatch.c standard powerpc/powerpc/sc_machdep.c optional sc powerpc/powerpc/setjmp.S standard powerpc/powerpc/sigcode.S standard +powerpc/powerpc/stack_machdep.c optional ddb | stack powerpc/powerpc/suswintr.c standard powerpc/powerpc/syncicache.c standard powerpc/powerpc/sys_machdep.c standard diff --git a/sys/conf/files.sparc64 b/sys/conf/files.sparc64 index 5f29180..3a0f6f0 100644 --- a/sys/conf/files.sparc64 +++ b/sys/conf/files.sparc64 @@ -124,6 +124,7 @@ sparc64/sparc64/rtc.c optional rtc ebus | rtc isa sparc64/sparc64/rwindow.c standard sparc64/sparc64/sc_machdep.c optional sc sparc64/sparc64/spitfire.c standard +sparc64/sparc64/stack_machdep.c optional ddb | stack sparc64/sparc64/support.S standard sparc64/sparc64/sys_machdep.c standard sparc64/sparc64/swtch.S standard diff --git a/sys/conf/files.sun4v b/sys/conf/files.sun4v index 37dfc32..700ca8a 100644 --- a/sys/conf/files.sun4v +++ b/sys/conf/files.sun4v @@ -74,6 +74,7 @@ sparc64/sparc64/prof_machdep.c optional profiling-routine sparc64/sparc64/rwindow.c standard sun4v/sun4v/rtc.c standard sun4v/sun4v/simdisk.c optional simulator +sun4v/sun4v/stack_machdep.c optional ddb | stack sun4v/sun4v/support.S standard sparc64/sparc64/sys_machdep.c standard sun4v/sun4v/swtch.S standard diff --git a/sys/conf/options b/sys/conf/options index 143c0aa..3f9769a 100644 --- a/sys/conf/options +++ b/sys/conf/options @@ -140,6 +140,7 @@ SHOW_BUSYBUFS SLEEPQUEUE_PROFILING SLHCI_DEBUG opt_slhci.h SPX_HACK +STACK opt_stack.h SUIDDIR MSGMNB opt_sysvipc.h MSGMNI opt_sysvipc.h diff --git a/sys/i386/conf/GENERIC b/sys/i386/conf/GENERIC index fc1b5a0..f9e87c3 100644 --- a/sys/i386/conf/GENERIC +++ b/sys/i386/conf/GENERIC @@ -54,6 +54,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/i386/i386/db_trace.c b/sys/i386/i386/db_trace.c index 2ac0fcf..94ab08c 100644 --- a/sys/i386/i386/db_trace.c +++ b/sys/i386/i386/db_trace.c @@ -31,13 +31,13 @@ __FBSDID("$FreeBSD$"); #include <sys/systm.h> #include <sys/kdb.h> #include <sys/proc.h> -#include <sys/stack.h> #include <sys/sysent.h> #include <machine/cpu.h> #include <machine/md_var.h> #include <machine/pcb.h> #include <machine/reg.h> +#include <machine/stack.h> #include <vm/vm.h> #include <vm/vm_param.h> @@ -166,18 +166,6 @@ db_ss(struct db_variable *vp, db_expr_t *valuep, int op) return (1); } -/* - * Stack trace. - */ -#define INKERNEL(va) (((vm_offset_t)(va)) >= USRSTACK && \ - ((vm_offset_t)(va)) < VM_MAX_KERNEL_ADDRESS) - -struct i386_frame { - struct i386_frame *f_frame; - int f_retaddr; - int f_arg0; -}; - #define NORMAL 0 #define TRAP 1 #define INTERRUPT 2 @@ -537,32 +525,6 @@ db_trace_thread(struct thread *thr, int count) ctx->pcb_eip, count)); } -void -stack_save(struct stack *st) -{ - struct i386_frame *frame; - vm_offset_t callpc; - register_t ebp; - - stack_zero(st); - __asm __volatile("movl %%ebp,%0" : "=r" (ebp)); - frame = (struct i386_frame *)ebp; - while (1) { - if (!INKERNEL(frame)) - break; - callpc = frame->f_retaddr; - if (!INKERNEL(callpc)) - break; - if (stack_put(st, callpc) == -1) - break; - if (frame->f_frame <= frame || - (vm_offset_t)frame->f_frame >= - (vm_offset_t)ebp + KSTACK_PAGES * PAGE_SIZE) - break; - frame = frame->f_frame; - } -} - int i386_set_watch(watchnum, watchaddr, size, access, d) int watchnum; diff --git a/sys/i386/i386/stack_machdep.c b/sys/i386/i386/stack_machdep.c new file mode 100644 index 0000000..482c102 --- /dev/null +++ b/sys/i386/i386/stack_machdep.c @@ -0,0 +1,89 @@ +/*- + * 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. + * + * $FreeBSD$ + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/proc.h> +#include <sys/stack.h> + +#include <machine/pcb.h> +#include <machine/stack.h> + +#include <vm/vm.h> +#include <vm/vm_param.h> +#include <vm/pmap.h> + +static void +stack_capture(struct stack *st, register_t ebp) +{ + struct i386_frame *frame; + vm_offset_t callpc; + + stack_zero(st); + frame = (struct i386_frame *)ebp; + while (1) { + if (!INKERNEL(frame)) + break; + callpc = frame->f_retaddr; + if (!INKERNEL(callpc)) + break; + if (stack_put(st, callpc) == -1) + break; + if (frame->f_frame <= frame || + (vm_offset_t)frame->f_frame >= + (vm_offset_t)ebp + KSTACK_PAGES * PAGE_SIZE) + break; + frame = frame->f_frame; + } +} + +void +stack_save_td(struct stack *st, struct thread *td) +{ + register_t ebp; + + if (TD_IS_SWAPPED(td)) + panic("stack_save_td: swapped"); + if (TD_IS_RUNNING(td)) + panic("stack_save_td: running"); + + ebp = td->td_pcb->pcb_ebp; + stack_capture(st, ebp); +} + +void +stack_save(struct stack *st) +{ + register_t ebp; + + __asm __volatile("movl %%ebp,%0" : "=r" (ebp)); + stack_capture(st, ebp); +} diff --git a/sys/i386/include/stack.h b/sys/i386/include/stack.h new file mode 100644 index 0000000..78caae0 --- /dev/null +++ b/sys/i386/include/stack.h @@ -0,0 +1,44 @@ +/*- + * Mach Operating System + * Copyright (c) 1991,1990 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie the + * rights to redistribute these changes. + * + * $FreeBSD$ + */ + +#ifndef _MACHINE_STACK_H_ +#define _MACHINE_STACK_H_ + +/* + * Stack trace. + */ +#define INKERNEL(va) (((vm_offset_t)(va)) >= USRSTACK && \ + ((vm_offset_t)(va)) < VM_MAX_KERNEL_ADDRESS) + +struct i386_frame { + struct i386_frame *f_frame; + int f_retaddr; + int f_arg0; +}; + +#endif /* !_MACHINE_STACK_H_ */ diff --git a/sys/ia64/conf/GENERIC b/sys/ia64/conf/GENERIC index 2fa5086..84a1fb7 100644 --- a/sys/ia64/conf/GENERIC +++ b/sys/ia64/conf/GENERIC @@ -50,6 +50,7 @@ options SCSI_DELAY=5000 # Delay (in ms) before probing SCSI options SMP # Symmetric Multi-Processor support options SOFTUPDATES # Enable FFS soft updates support options UFS_GJOURNAL # Enable gjournal-based UFS journaling +options STACK # stack(9) support options SYSVMSG # SYSV-style message queues options SYSVSEM # SYSV-style semaphores options SYSVSHM # SYSV-style shared memory diff --git a/sys/ia64/ia64/db_machdep.c b/sys/ia64/ia64/db_machdep.c index 6579f3b..cdd60ab 100644 --- a/sys/ia64/ia64/db_machdep.c +++ b/sys/ia64/ia64/db_machdep.c @@ -597,18 +597,6 @@ db_trace_thread(struct thread *td, int count) return (db_backtrace(td, ctx, count)); } -void -stack_save(struct stack *st) -{ - - stack_zero(st); - /* - * Nothing for now. - * Is libuwx reentrant? - * Can unw_create* sleep? - */ -} - #ifdef EXCEPTION_TRACING extern long xtrace[]; diff --git a/sys/ia64/ia64/stack_machdep.c b/sys/ia64/ia64/stack_machdep.c new file mode 100644 index 0000000..5e513ea --- /dev/null +++ b/sys/ia64/ia64/stack_machdep.c @@ -0,0 +1,57 @@ +/*- + * 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/systm.h> +#include <sys/proc.h> +#include <sys/stack.h> + +void +stack_save_td(struct stack *st, struct thread *td) +{ + + if (TD_IS_SWAPPED(td)) + panic("stack_save_td: swapped"); + if (TD_IS_RUNNING(td)) + panic("stack_save_td: running"); + + stack_zero(st); +} + +void +stack_save(struct stack *st) +{ + + stack_zero(st); + /* + * Nothing for now. + * Is libuwx reentrant? + * Can unw_create* sleep? + */ +} diff --git a/sys/kern/subr_stack.c b/sys/kern/subr_stack.c index e3cf156..db03ccf 100644 --- a/sys/kern/subr_stack.c +++ b/sys/kern/subr_stack.c @@ -105,6 +105,7 @@ stack_print(struct stack *st) } } +#ifdef DDB void stack_print_ddb(struct stack *st) { @@ -120,6 +121,7 @@ stack_print_ddb(struct stack *st) namebuf, offset); } } +#endif /* * Two print routines -- one for use from DDB and DDB-like contexts, the diff --git a/sys/pc98/conf/GENERIC b/sys/pc98/conf/GENERIC index 3436984..41e95d5 100644 --- a/sys/pc98/conf/GENERIC +++ b/sys/pc98/conf/GENERIC @@ -57,6 +57,7 @@ options EPSON_BOUNCEDMA # use bounce buffer for 15-16M #options EPSON_MEMWIN # EPSON memory window support #options LINE30 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/powerpc/conf/GENERIC b/sys/powerpc/conf/GENERIC index ef31949..7f1cc40 100644 --- a/sys/powerpc/conf/GENERIC +++ b/sys/powerpc/conf/GENERIC @@ -55,6 +55,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) syscall trace 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/powerpc/include/stack.h b/sys/powerpc/include/stack.h new file mode 100644 index 0000000..c433a9f --- /dev/null +++ b/sys/powerpc/include/stack.h @@ -0,0 +1,36 @@ +/*- + * Mach Operating System + * Copyright (c) 1992 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + * + * $FreeBSD$ + */ + +#ifndef _MACHINE_STACK_H_ +#define _MACHINE_STACK_H_ + +extern int trapexit[]; +extern int asttrapexit[]; +extern int end[]; + +#endif /* !_MACHINE_STACK_H_ */ diff --git a/sys/powerpc/powerpc/db_trace.c b/sys/powerpc/powerpc/db_trace.c index 188e028..3fdfc76 100644 --- a/sys/powerpc/powerpc/db_trace.c +++ b/sys/powerpc/powerpc/db_trace.c @@ -41,6 +41,7 @@ #include <machine/db_machdep.h> #include <machine/pcb.h> #include <machine/spr.h> +#include <machine/stack.h> #include <machine/trap.h> #include <ddb/ddb.h> @@ -96,10 +97,6 @@ struct db_variable db_regs[] = { }; struct db_variable *db_eregs = db_regs + sizeof (db_regs)/sizeof (db_regs[0]); -extern int trapexit[]; -extern int asttrapexit[]; -extern int end[]; - /* * register variable handling */ @@ -287,37 +284,3 @@ db_trace_thread(struct thread *td, int count) ctx = kdb_thr_ctx(td); return (db_backtrace(td, (db_addr_t)ctx->pcb_sp, count)); } - -void -stack_save(struct stack *st) -{ - vm_offset_t callpc; - db_addr_t stackframe; - - stack_zero(st); - stackframe = (db_addr_t)__builtin_frame_address(1); - if (stackframe < PAGE_SIZE) - return; - while (1) { - stackframe = *(db_addr_t *)stackframe; - if (stackframe < PAGE_SIZE) - break; - callpc = *(vm_offset_t *)(stackframe + 4) - 4; - if ((callpc & 3) || (callpc < 0x100)) - break; - - /* - * Don't bother traversing trap-frames - there should - * be enough info down to the frame to work out where - * things are going wrong. Plus, prevents this shortened - * version of code from accessing user-space frames - */ - if (callpc + 4 == (db_addr_t) &trapexit || - callpc + 4 == (db_addr_t) &asttrapexit) - break; - - if (stack_put(st, callpc) == -1) - break; - } -} - diff --git a/sys/powerpc/powerpc/stack_machdep.c b/sys/powerpc/powerpc/stack_machdep.c new file mode 100644 index 0000000..7bc6fd4 --- /dev/null +++ b/sys/powerpc/powerpc/stack_machdep.c @@ -0,0 +1,97 @@ +/*- + * 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/pmap.h> +#include <vm/vm_extern.h> + +#include <machine/db_machdep.h> +#include <machine/pcb.h> +#include <machine/spr.h> +#include <machine/stack.h> +#include <machine/trap.h> + +static void +stack_capture(struct stack *st, register_t frame) +{ + vm_offset_t callpc; + + stack_zero(st); + if (frame < PAGE_SIZE) + return; + while (1) { + frame = *(register_t *)frame; + if (frame < PAGE_SIZE) + break; + callpc = *(vm_offset_t *)(frame + 4) - 4; + if ((callpc & 3) || (callpc < 0x100)) + break; + + /* + * Don't bother traversing trap-frames - there should + * be enough info down to the frame to work out where + * things are going wrong. Plus, prevents this shortened + * version of code from accessing user-space frames + */ + if (callpc + 4 == (register_t) &trapexit || + callpc + 4 == (register_t) &asttrapexit) + break; + + if (stack_put(st, callpc) == -1) + break; + } +} + +void +stack_save_td(struct stack *st, struct thread *td) +{ + register_t frame; + + if (TD_IS_SWAPPED(td)) + panic("stack_save_td: swapped"); + if (TD_IS_RUNNING(td)) + panic("stack_save_td: running"); + + frame = td->td_pcb->pcb_sp; + stack_capture(st, frame); +} + +void +stack_save(struct stack *st) +{ + register_t frame; + + frame = (register_t)__builtin_frame_address(1); + stack_capture(st, frame); +} 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); +} diff --git a/sys/sun4v/conf/GENERIC b/sys/sun4v/conf/GENERIC index d67c1dd..bfc2aaa 100644 --- a/sys/sun4v/conf/GENERIC +++ b/sys/sun4v/conf/GENERIC @@ -55,6 +55,7 @@ options COMPAT_43TTY # BSD 4.3 TTY compat [KEEP THIS!] options COMPAT_FREEBSD5 # Compatible with FreeBSD5 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/sun4v/include/stack.h b/sys/sun4v/include/stack.h new file mode 100644 index 0000000..8131ce5 --- /dev/null +++ b/sys/sun4v/include/stack.h @@ -0,0 +1,35 @@ +/*- + * 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_ + +#define INKERNEL(va) \ + ((va) >= VM_MIN_KERNEL_ADDRESS && (va) <= VM_MAX_KERNEL_ADDRESS) + +#endif /* !_MACHINE_STACK_H_ */ diff --git a/sys/sun4v/sun4v/db_trace.c b/sys/sun4v/sun4v/db_trace.c index 5c07ecc..632d256 100644 --- a/sys/sun4v/sun4v/db_trace.c +++ b/sys/sun4v/sun4v/db_trace.c @@ -40,6 +40,7 @@ #include <machine/cpu.h> #include <machine/pcb.h> +#include <machine/stack.h> #include <machine/trap.h> #include <machine/vmparam.h> @@ -49,9 +50,6 @@ #include <ddb/db_variables.h> #include <ddb/db_watch.h> -#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) @@ -304,23 +302,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; - if (stack_put(st, callpc) == -1) - break; - fp = (struct frame *)(fp->fr_fp + SPOFF); - } -} diff --git a/sys/sun4v/sun4v/stack_machdep.c b/sys/sun4v/sun4v/stack_machdep.c new file mode 100644 index 0000000..2ee0ff3 --- /dev/null +++ b/sys/sun4v/sun4v/stack_machdep.c @@ -0,0 +1,85 @@ +/*- + * 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; + 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); +} diff --git a/sys/sys/stack.h b/sys/sys/stack.h index ca83472..6bd52ab 100644 --- a/sys/sys/stack.h +++ b/sys/sys/stack.h @@ -59,6 +59,8 @@ void stack_ktr(u_int, const char *, int, struct stack *, u_int, int); #endif /* MD Routine. */ +struct thread; void stack_save(struct stack *); +void stack_save_td(struct stack *, struct thread *); #endif |