diff options
author | marius <marius@FreeBSD.org> | 2006-02-19 11:54:46 +0000 |
---|---|---|
committer | marius <marius@FreeBSD.org> | 2006-02-19 11:54:46 +0000 |
commit | 8fac408a7262b12dce6d506344068ddc9964015c (patch) | |
tree | a990f489d0898146ccba742f0324af70fa95baf8 /sys/sparc64 | |
parent | d07e9ef4b2d775909a4e2e6c891922e109731b14 (diff) | |
download | FreeBSD-src-8fac408a7262b12dce6d506344068ddc9964015c.zip FreeBSD-src-8fac408a7262b12dce6d506344068ddc9964015c.tar.gz |
- Don't bother traversing trap frames in stack_save(). This fixes panics
when option DEBUG_LOCKS is used. Trap frames are determined by checking
whether the caller was one of the tl0_*() or tl1_*() asm functions via
a newly added pair of dummy symbols in exception.S which mark the begin
and end of these functions. The tl_trap_* pair marks those in the special
.trap section and the tl_text_* in the regular .text section. Because
of their performance penalty db_search_symbol()/db_symbol_values() and
linker_ddb_search_symbol()/linker_ddb_symbol_values() aren't used here
for determining the caller, with db_search_symbol()/db_symbol_values()
additionally not being reentrant.
- For consistency, change db_backtrace() to also use the new markers for
determining the tl0_*() and tl1_*() asm functions instead of bcmp()'ing
the symbol name.
- Use FBSDID in db_trace.c.
PR: 93226
Based on a patch by: Antoine Brodin <antoine.brodin@laposte.net>
Ok'ed by: jhb
Diffstat (limited to 'sys/sparc64')
-rw-r--r-- | sys/sparc64/sparc64/db_trace.c | 22 | ||||
-rw-r--r-- | sys/sparc64/sparc64/exception.S | 16 |
2 files changed, 34 insertions, 4 deletions
diff --git a/sys/sparc64/sparc64/db_trace.c b/sys/sparc64/sparc64/db_trace.c index 66cc76b..bb5f60c 100644 --- a/sys/sparc64/sparc64/db_trace.c +++ b/sys/sparc64/sparc64/db_trace.c @@ -22,10 +22,11 @@ * 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/kdb.h> @@ -49,6 +50,11 @@ #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) @@ -259,8 +265,10 @@ db_backtrace(struct thread *td, struct frame *fp, int count) name = "(null)"; fp = (struct frame *)(db_get_value((db_addr_t)&fp->fr_fp, sizeof(fp->fr_fp), FALSE) + SPOFF); - if (bcmp(name, "tl0_", 4) == 0 || - bcmp(name, "tl1_", 4) == 0) { + if ((value > (u_long)tl_trap_begin && + value < (u_long)tl_trap_end) || + (value > (u_long)tl_text_begin && + value < (u_long)tl_text_end)) { tf = (struct trapframe *)(fp + 1); npc = db_get_value((db_addr_t)&tf->tf_tpc, sizeof(tf->tf_tpc), FALSE); @@ -307,6 +315,12 @@ stack_save(struct stack *st) callpc = fp->fr_pc; if (!INKERNEL(callpc)) break; + /* Don't bother traversing trap frames. */ + if ((callpc > (u_long)tl_trap_begin && + callpc < (u_long)tl_trap_end) || + (callpc > (u_long)tl_text_begin && + callpc < (u_long)tl_text_end)) + break; if (stack_put(st, callpc) == -1) break; fp = (struct frame *)(fp->fr_fp + SPOFF); diff --git a/sys/sparc64/sparc64/exception.S b/sys/sparc64/sparc64/exception.S index d3fcdb8..830a724 100644 --- a/sys/sparc64/sparc64/exception.S +++ b/sys/sparc64/sparc64/exception.S @@ -166,6 +166,10 @@ __FBSDID("$FreeBSD$"); ldx [ASP_REG + 0], %g1 ; \ inc 16, ASP_REG + .globl tl_text_begin +tl_text_begin: + nop + ENTRY(tl1_kstack_fault) rdpr %tl, %g1 1: cmp %g1, 2 @@ -1818,6 +1822,10 @@ END(tl1_spill_topcb) .endm .sect .trap + .globl tl_trap_begin +tl_trap_begin: + nop + .align 0x8000 .globl tl0_base @@ -2015,6 +2023,10 @@ tl1_breakpoint: tl1_gen T_RSTRWP_VIRT ! 0x303 tl1_reserved 252 ! 0x304-0x3ff + .globl tl_trap_end +tl_trap_end: + nop + /* * User trap entry point. * @@ -2901,6 +2913,10 @@ ENTRY(tl1_intr) retry END(tl1_intr) + .globl tl_text_end +tl_text_end: + nop + /* * Freshly forked processes come here when switched to for the first time. * The arguments to fork_exit() have been setup in the locals, we must move |