summaryrefslogtreecommitdiffstats
path: root/sys/amd64/amd64/trap.c
diff options
context:
space:
mode:
authordg <dg@FreeBSD.org>1995-12-19 14:30:50 +0000
committerdg <dg@FreeBSD.org>1995-12-19 14:30:50 +0000
commit95d4407d256f0ffa1815a33f1ecbb69af4758281 (patch)
tree0f3a6a4cd34125a3b374024be9001afc03573a4c /sys/amd64/amd64/trap.c
parent655b27e73b172bddc17c1c8cef53b4cdb00537d9 (diff)
downloadFreeBSD-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.c34
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
OpenPOWER on IntegriCloud