- 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
This commit is contained in:
Marius Strobl 2006-02-19 11:54:46 +00:00
parent f50a4cf27c
commit 9789208431
2 changed files with 34 additions and 4 deletions

View File

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

View File

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