diff options
author | dg <dg@FreeBSD.org> | 1995-12-19 14:30:50 +0000 |
---|---|---|
committer | dg <dg@FreeBSD.org> | 1995-12-19 14:30:50 +0000 |
commit | 95d4407d256f0ffa1815a33f1ecbb69af4758281 (patch) | |
tree | 0f3a6a4cd34125a3b374024be9001afc03573a4c /sys/amd64/amd64/trap.c | |
parent | 655b27e73b172bddc17c1c8cef53b4cdb00537d9 (diff) | |
download | FreeBSD-src-95d4407d256f0ffa1815a33f1ecbb69af4758281.zip FreeBSD-src-95d4407d256f0ffa1815a33f1ecbb69af4758281.tar.gz |
Implemented a (sorely needed for years) double fault handler to catch stack
overflows.
It sure would be nice if there was an unmapped page between the PCB and
the stack (and that the size of the stack was configurable!). With the
way things are now, the PCB will get clobbered before the double fault
handler gets control, making somewhat of a mess of things. Despite this,
it is still fairly easy to poke around in the overflowed stack to figure
out the cause.
Diffstat (limited to 'sys/amd64/amd64/trap.c')
-rw-r--r-- | sys/amd64/amd64/trap.c | 34 |
1 files changed, 31 insertions, 3 deletions
diff --git a/sys/amd64/amd64/trap.c b/sys/amd64/amd64/trap.c index 21f1f8e..acee977 100644 --- a/sys/amd64/amd64/trap.c +++ b/sys/amd64/amd64/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 |