diff options
author | jhb <jhb@FreeBSD.org> | 2004-09-09 20:39:31 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2004-09-09 20:39:31 +0000 |
commit | 860ec87f051642734c2c738bd5fbc987dd8f4512 (patch) | |
tree | 3023d2f420ad51d3fd30feda081e815f0b34ef44 | |
parent | 5c2e163300e7da98d8c537c98b738e90c0933f0a (diff) | |
download | FreeBSD-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.c | 20 |
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. */ |