diff options
Diffstat (limited to 'sys/kern/subr_trap.c')
-rw-r--r-- | sys/kern/subr_trap.c | 34 |
1 files changed, 31 insertions, 3 deletions
diff --git a/sys/kern/subr_trap.c b/sys/kern/subr_trap.c index 21f1f8e..acee977 100644 --- a/sys/kern/subr_trap.c +++ b/sys/kern/subr_trap.c @@ -35,7 +35,7 @@ * SUCH DAMAGE. * * from: @(#)trap.c 7.4 (Berkeley) 5/13/91 - * $Id: trap.c,v 1.65 1995/12/14 08:21:29 phk Exp $ + * $Id: trap.c,v 1.66 1995/12/14 14:35:36 peter Exp $ */ /* @@ -89,8 +89,9 @@ extern int trapwrite __P((unsigned addr)); extern void syscall __P((struct trapframe frame)); extern void linux_syscall __P((struct trapframe frame)); -static int trap_pfault __P((struct trapframe *, int)); -static void trap_fatal __P((struct trapframe *)); +static int trap_pfault __P((struct trapframe *, int)); +static void trap_fatal __P((struct trapframe *)); +void dblfault_handler __P((void)); extern inthand_t IDTVEC(syscall); @@ -756,6 +757,33 @@ trap_fatal(frame) } /* + * Double fault handler. Called when a fault occurs while writing + * a frame for a trap/exception onto the stack. This usually occurs + * when the stack overflows (such is the case with infinite recursion, + * for example). + * + * XXX Note that the current PTD gets replaced by IdlePTD when the + * task switch occurs. This means that the stack that was active at + * the time of the double fault is not available at <kstack> unless + * the machine was idlewhen the double fault occurred. This downside + * of this is that "trace <ebp>" in ddb won't work. + */ +void +dblfault_handler() +{ + struct pcb *pcb = curpcb; + + if (pcb != NULL) { + printf("\nFatal double fault:\n"); + printf("eip = 0x%x\n", pcb->pcb_tss.tss_eip); + printf("esp = 0x%x\n", pcb->pcb_tss.tss_esp); + printf("ebp = 0x%x\n", pcb->pcb_tss.tss_ebp); + } + + panic("double fault"); +} + +/* * Compensate for 386 brain damage (missing URKR). * This is a little simpler than the pagefault handler in trap() because * it the page tables have already been faulted in and high addresses |