aboutsummaryrefslogtreecommitdiff
path: root/sys/i386/i386/db_trace.c
diff options
context:
space:
mode:
authorJohn Baldwin <jhb@FreeBSD.org>2005-01-18 03:48:02 +0000
committerJohn Baldwin <jhb@FreeBSD.org>2005-01-18 03:48:02 +0000
commitbb5d43ae2abfac6011dd236f672d4f617e46f9cd (patch)
tree0cc12c8a033abd88c075c58036cc3a31173d8d39 /sys/i386/i386/db_trace.c
parent9196a9005ed54ab9e984354aaadd51ffa35454ed (diff)
downloadsrc-bb5d43ae2abfac6011dd236f672d4f617e46f9cd.tar.gz
src-bb5d43ae2abfac6011dd236f672d4f617e46f9cd.zip
Unbreak stack traces across double faults. In a particular edge case
(calling a __dead2 function such as panic() at the end of a function), the saved %eip on the stack will actually not be part of the function that executed a call instruction but instead will be the first instruction of the next function in the text. This happens with dblfault_handler() and syscall() for example. Work around this in the one place it matters by looking at the saved %eip - 1 to determine the calling function when we check for "magic" frames. MFC after: 2 weeks
Notes
Notes: svn path=/head/; revision=140401
Diffstat (limited to 'sys/i386/i386/db_trace.c')
-rw-r--r--sys/i386/i386/db_trace.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/sys/i386/i386/db_trace.c b/sys/i386/i386/db_trace.c
index b649aa425ed2..c26ba368df08 100644
--- a/sys/i386/i386/db_trace.c
+++ b/sys/i386/i386/db_trace.c
@@ -286,10 +286,16 @@ db_nextframe(struct i386_frame **fp, db_addr_t *ip, struct thread *td)
ebp = db_get_value((int) &(*fp)->f_frame, 4, FALSE);
/*
- * Figure out frame type.
+ * Figure out frame type. We look at the address just before
+ * the saved instruction pointer as the saved EIP is after the
+ * call function, and if the function being called is marked as
+ * dead (such as panic() at the end of dblfault_handler()), then
+ * the instruction at the saved EIP will be part of a different
+ * function (syscall() in this example) rather than the one that
+ * actually made the call.
*/
frame_type = NORMAL;
- sym = db_search_symbol(eip, DB_STGY_ANY, &offset);
+ sym = db_search_symbol(eip - 1, DB_STGY_ANY, &offset);
db_symbol_values(sym, &name, NULL);
if (name != NULL) {
if (strcmp(name, "calltrap") == 0 ||