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:
parent
cdc03cc897
commit
3c90d1ea74
@ -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 .
|
||||
|
@ -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;
|
||||
|
87
sys/amd64/amd64/stack_machdep.c
Normal file
87
sys/amd64/amd64/stack_machdep.c
Normal 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);
|
||||
}
|
@ -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
44
sys/amd64/include/stack.h
Normal 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_ */
|
@ -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]);
|
||||
}
|
||||
}
|
||||
|
76
sys/arm/arm/stack_machdep.c
Normal file
76
sys/arm/arm/stack_machdep.c
Normal 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
42
sys/arm/include/stack.h
Normal 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_ */
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
89
sys/i386/i386/stack_machdep.c
Normal file
89
sys/i386/i386/stack_machdep.c
Normal 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
44
sys/i386/include/stack.h
Normal 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_ */
|
@ -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
|
||||
|
@ -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[];
|
||||
|
57
sys/ia64/ia64/stack_machdep.c
Normal file
57
sys/ia64/ia64/stack_machdep.c
Normal 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?
|
||||
*/
|
||||
}
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
36
sys/powerpc/include/stack.h
Normal file
36
sys/powerpc/include/stack.h
Normal 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_ */
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
97
sys/powerpc/powerpc/stack_machdep.c
Normal file
97
sys/powerpc/powerpc/stack_machdep.c
Normal 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);
|
||||
}
|
@ -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
|
||||
|
40
sys/sparc64/include/stack.h
Normal file
40
sys/sparc64/include/stack.h
Normal 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_ */
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
90
sys/sparc64/sparc64/stack_machdep.c
Normal file
90
sys/sparc64/sparc64/stack_machdep.c
Normal 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);
|
||||
}
|
@ -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
35
sys/sun4v/include/stack.h
Normal 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_ */
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
85
sys/sun4v/sun4v/stack_machdep.c
Normal file
85
sys/sun4v/sun4v/stack_machdep.c
Normal 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);
|
||||
}
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user