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)
This commit is contained in:
Robert Watson 2007-12-02 20:40:35 +00:00
parent cdc03cc897
commit 3c90d1ea74
40 changed files with 883 additions and 232 deletions

View File

@ -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 .

View File

@ -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;

View File

@ -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);
}

View File

@ -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

44
sys/amd64/include/stack.h Normal file
View File

@ -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_ */

View File

@ -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]);
}
}

View File

@ -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);
}

42
sys/arm/include/stack.h Normal file
View File

@ -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_ */

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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);
}

44
sys/i386/include/stack.h Normal file
View File

@ -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_ */

View File

@ -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

View File

@ -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[];

View File

@ -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?
*/
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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_ */

View File

@ -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;
}
}

View File

@ -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);
}

View File

@ -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

View File

@ -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_ */

View File

@ -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);
}
}

View File

@ -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);
}

View File

@ -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

35
sys/sun4v/include/stack.h Normal file
View File

@ -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_ */

View File

@ -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);
}
}

View File

@ -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);
}

View File

@ -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