- 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:
parent
f50a4cf27c
commit
9789208431
@ -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);
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user