summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2004-09-09 20:39:31 +0000
committerjhb <jhb@FreeBSD.org>2004-09-09 20:39:31 +0000
commit860ec87f051642734c2c738bd5fbc987dd8f4512 (patch)
tree3023d2f420ad51d3fd30feda081e815f0b34ef44
parent5c2e163300e7da98d8c537c98b738e90c0933f0a (diff)
downloadFreeBSD-src-860ec87f051642734c2c738bd5fbc987dd8f4512.zip
FreeBSD-src-860ec87f051642734c2c738bd5fbc987dd8f4512.tar.gz
Teach the stack trace code how to step across a double fault when stepping
across frames. Basically, if the current frame is for the 'dblfault_handler' function, then get the next %eip and %ebp values to use from the original TSS of the thread that has the saved state when the double fault triggered. MFC after: 4 days
-rw-r--r--sys/i386/i386/db_trace.c20
1 files changed, 20 insertions, 0 deletions
diff --git a/sys/i386/i386/db_trace.c b/sys/i386/i386/db_trace.c
index d7ae3e3..ca3435e 100644
--- a/sys/i386/i386/db_trace.c
+++ b/sys/i386/i386/db_trace.c
@@ -179,6 +179,7 @@ struct i386_frame {
#define TRAP 1
#define INTERRUPT 2
#define SYSCALL 3
+#define DOUBLE_FAULT 4
static void db_nextframe(struct i386_frame **, db_addr_t *, struct thread *);
static int db_numargs(struct i386_frame *);
@@ -300,6 +301,8 @@ db_nextframe(struct i386_frame **fp, db_addr_t *ip, struct thread *td)
else if (strcmp(name, "Xlcall_syscall") == 0 ||
strcmp(name, "Xint0x80_syscall") == 0)
frame_type = SYSCALL;
+ else if (strcmp(name, "dblfault_handler") == 0)
+ frame_type = DOUBLE_FAULT;
}
/*
@@ -314,6 +317,23 @@ db_nextframe(struct i386_frame **fp, db_addr_t *ip, struct thread *td)
db_print_stack_entry(name, 0, 0, 0, eip);
/*
+ * For a double fault, we have to snag the values from the
+ * previous TSS since a double fault uses a task gate to
+ * switch to a known good state.
+ */
+ if (frame_type == DOUBLE_FAULT) {
+ esp = PCPU_GET(common_tss.tss_esp);
+ eip = PCPU_GET(common_tss.tss_eip);
+ ebp = PCPU_GET(common_tss.tss_ebp);
+ db_printf(
+ "--- trap 0x17, eip = %#r, esp = %#r, ebp = %#r ---\n",
+ eip, esp, ebp);
+ *ip = (db_addr_t) eip;
+ *fp = (struct i386_frame *) ebp;
+ return;
+ }
+
+ /*
* Point to base of trapframe which is just above the
* current frame.
*/
OpenPOWER on IntegriCloud