diff options
author | grehan <grehan@FreeBSD.org> | 2005-12-23 13:05:27 +0000 |
---|---|---|
committer | grehan <grehan@FreeBSD.org> | 2005-12-23 13:05:27 +0000 |
commit | b14a15198504a2347d4337c611b8d2bd71f86f2f (patch) | |
tree | adae55e3d7e1d097e934d8bbd40da968892f9460 /sys/powerpc | |
parent | fc4af16293b1158c6a7e8c5bf02843d70eb5c751 (diff) | |
download | FreeBSD-src-b14a15198504a2347d4337c611b8d2bd71f86f2f.zip FreeBSD-src-b14a15198504a2347d4337c611b8d2bd71f86f2f.tar.gz |
Mark the return address of the call to ast() in the generic trap
handling code so the stack trace unwinders don't start trying to
go into user-space.
Found by trying to create core dumps with a KTR_COMPILE/KTR_GEOM
kernel, which results in a stack_save() call in the ast() coredump
path - this created a panic, and then calling 'trace' in ddb resulted
in the black screen of death after printing out most of the backtrace.
Diffstat (limited to 'sys/powerpc')
-rw-r--r-- | sys/powerpc/aim/trap_subr.S | 2 | ||||
-rw-r--r-- | sys/powerpc/powerpc/db_trace.c | 14 | ||||
-rw-r--r-- | sys/powerpc/powerpc/trap_subr.S | 2 |
3 files changed, 13 insertions, 5 deletions
diff --git a/sys/powerpc/aim/trap_subr.S b/sys/powerpc/aim/trap_subr.S index c719917..06ed891 100644 --- a/sys/powerpc/aim/trap_subr.S +++ b/sys/powerpc/aim/trap_subr.S @@ -438,6 +438,8 @@ CNAME(trapexit): isync addi %r3,%r1,8 bl CNAME(ast) + .globl CNAME(asttrapexit) /* backtrace code sentinel #2 */ +CNAME(asttrapexit): b trapexit /* test ast ret value ? */ 1: FRAME_LEAVE(PC_TEMPSAVE) diff --git a/sys/powerpc/powerpc/db_trace.c b/sys/powerpc/powerpc/db_trace.c index 131beef..e70f5e1 100644 --- a/sys/powerpc/powerpc/db_trace.c +++ b/sys/powerpc/powerpc/db_trace.c @@ -97,6 +97,7 @@ 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[]; /* @@ -186,11 +187,13 @@ db_backtrace(struct thread *td, db_addr_t fp, int count) db_printf("0x%08x: ", stackframe); /* - * The trap code labels the return address from the - * call to C code as 'trapexit'. Use this to determine - * if the callframe has to traverse a saved trap context + * The trap code labels the return addresses from the + * call to C code as 'trapexit' and 'asttrapexit. Use this + * to determine if the callframe has to traverse a saved + * trap context */ - if (lr + 4 == (db_addr_t) &trapexit) { + if ((lr + 4 == (db_addr_t) &trapexit) || + (lr + 4 == (db_addr_t) &asttrapexit)) { const char *trapstr; struct trapframe *tf = (struct trapframe *) (stackframe+8); @@ -312,7 +315,8 @@ stack_save(struct stack *st) * things are going wrong. Plus, prevents this shortened * version of code from accessing user-space frames */ - if (callpc + 4 == (db_addr_t) &trapexit) + if (callpc + 4 == (db_addr_t) &trapexit || + callpc + 4 == (db_addr_t) &asttrapexit) break; if (stack_put(st, callpc) == -1) diff --git a/sys/powerpc/powerpc/trap_subr.S b/sys/powerpc/powerpc/trap_subr.S index c719917..06ed891 100644 --- a/sys/powerpc/powerpc/trap_subr.S +++ b/sys/powerpc/powerpc/trap_subr.S @@ -438,6 +438,8 @@ CNAME(trapexit): isync addi %r3,%r1,8 bl CNAME(ast) + .globl CNAME(asttrapexit) /* backtrace code sentinel #2 */ +CNAME(asttrapexit): b trapexit /* test ast ret value ? */ 1: FRAME_LEAVE(PC_TEMPSAVE) |