diff options
author | Philip Guenther <guenther@cvs.openbsd.org> | 2015-03-31 04:40:48 +0000 |
---|---|---|
committer | Philip Guenther <guenther@cvs.openbsd.org> | 2015-03-31 04:40:48 +0000 |
commit | 6fd9b6677b997cc8e45d906f8b48936b3988da93 (patch) | |
tree | a1fab1d92d9d5b9ec45018a7ee01043690f6d399 /sys/arch | |
parent | 5656753b5695cfdcf6cd7884914f61cea903e212 (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.c | 18 |
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 */ |