summaryrefslogtreecommitdiff
path: root/sys/arch
diff options
context:
space:
mode:
authorPhilip Guenther <guenther@cvs.openbsd.org>2015-03-31 04:40:48 +0000
committerPhilip Guenther <guenther@cvs.openbsd.org>2015-03-31 04:40:48 +0000
commit6fd9b6677b997cc8e45d906f8b48936b3988da93 (patch)
treea1fab1d92d9d5b9ec45018a7ee01043690f6d399 /sys/arch
parent5656753b5695cfdcf6cd7884914f61cea903e212 (diff)
Tracing across an interrupt frame was failing because the trace code thought
the interrupt frame was at the same address as the frame that was interrupted. Correct the calculated frame pointer for the interrupt frame to have the same offset to the struct trapframe on the stack as does syscall and trap. ok kettenis@ mlarkin@
Diffstat (limited to 'sys/arch')
-rw-r--r--sys/arch/amd64/amd64/db_trace.c18
1 files changed, 11 insertions, 7 deletions
diff --git a/sys/arch/amd64/amd64/db_trace.c b/sys/arch/amd64/amd64/db_trace.c
index 14e6fcfb4b6..03f1f8cb17a 100644
--- a/sys/arch/amd64/amd64/db_trace.c
+++ b/sys/arch/amd64/amd64/db_trace.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: db_trace.c,v 1.10 2015/03/22 05:41:50 guenther Exp $ */
+/* $OpenBSD: db_trace.c,v 1.11 2015/03/31 04:40:47 guenther Exp $ */
/* $NetBSD: db_trace.c,v 1.1 2003/04/26 18:39:27 fvdl Exp $ */
/*
@@ -108,7 +108,6 @@ struct x86_64_frame {
struct x86_64_frame *f_frame;
long f_retaddr;
long f_arg0;
- long f_arg1;
};
#define NONE 0
@@ -329,12 +328,17 @@ db_stack_trace_print(db_expr_t addr, boolean_t have_addr, db_expr_t count,
continue;
}
- if (is_trap == INTERRUPT)
- argp = &lastframe->f_arg1;
- else
- argp = &frame->f_arg0;
+ if (is_trap == INTERRUPT) {
+ /*
+ * Interrupt routines don't update %rbp, so it still
+ * points to the frame that was interrupted. Pull
+ * back to just above lastframe so we can find the
+ * trapframe as with syscalls and traps.
+ */
+ frame = (struct x86_64_frame *)&lastframe->f_retaddr;
+ }
lastframe = frame;
- db_nextframe(&frame, &callpc, argp, is_trap, pr);
+ db_nextframe(&frame, &callpc, &frame->f_arg0, is_trap, pr);
if (frame == 0) {
/* end of chain */