diff options
author | jhb <jhb@FreeBSD.org> | 2005-01-18 03:48:02 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2005-01-18 03:48:02 +0000 |
commit | 9819b0d8b7729a5d35dd923317e0bae41172832e (patch) | |
tree | 0cc12c8a033abd88c075c58036cc3a31173d8d39 /sys | |
parent | c09808e6cda3e0bef1923afeac9d8c0cf35dd9fe (diff) | |
download | FreeBSD-src-9819b0d8b7729a5d35dd923317e0bae41172832e.zip FreeBSD-src-9819b0d8b7729a5d35dd923317e0bae41172832e.tar.gz |
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
Diffstat (limited to 'sys')
-rw-r--r-- | sys/i386/i386/db_trace.c | 10 |
1 files changed, 8 insertions, 2 deletions
diff --git a/sys/i386/i386/db_trace.c b/sys/i386/i386/db_trace.c index b649aa4..c26ba36 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 || |