diff options
author | Bruno Larsen <blarsen@redhat.com> | 2022-08-19 15:11:28 +0200 |
---|---|---|
committer | Bruno Larsen <blarsen@redhat.com> | 2022-10-21 12:49:26 +0200 |
commit | 49d7cd733a7f1b87aa1d40318b3d7c2b65aca5ac (patch) | |
tree | 9b2192f62d8eb5eb4ed79e94aaf23b6f833833d8 /gdb/amd64-tdep.c | |
parent | 7c0cca765e4630a5b3b8df285c7b0f90b6cb41cc (diff) | |
download | gdb-49d7cd733a7f1b87aa1d40318b3d7c2b65aca5ac.zip gdb-49d7cd733a7f1b87aa1d40318b3d7c2b65aca5ac.tar.gz gdb-49d7cd733a7f1b87aa1d40318b3d7c2b65aca5ac.tar.bz2 |
Change calculation of frame_id by amd64 epilogue unwinder
When GDB is stopped at a ret instruction and no debug information is
available for unwinding, GDB defaults to the amd64 epilogue unwinder, to
be able to generate a decent backtrace. However, when calculating the
frame id, the epilogue unwinder generates information as if the return
instruction was the whole frame.
This was an issue especially when attempting to reverse debug, as GDB
would place a step_resume_breakpoint from the epilogue of a function if
we were to attempt to skip that function, and this breakpoint should
ideally have the current function's frame_id to avoid other problems
such as PR record/16678.
This commit changes the frame_id calculation for the amd64 epilogue,
so that it is always the same as the dwarf2 unwinder's frame_id.
It also adds a test to confirm that the frame_id will be the same,
regardless of using the epilogue unwinder or not, thanks to Andrew
Burgess.
Co-Authored-By: Andrew Burgess <aburgess@redhat.com>
Diffstat (limited to 'gdb/amd64-tdep.c')
-rw-r--r-- | gdb/amd64-tdep.c | 10 |
1 files changed, 5 insertions, 5 deletions
diff --git a/gdb/amd64-tdep.c b/gdb/amd64-tdep.c index a6894d8..bbfc509 100644 --- a/gdb/amd64-tdep.c +++ b/gdb/amd64-tdep.c @@ -2937,18 +2937,18 @@ amd64_epilogue_frame_cache (frame_info_ptr this_frame, void **this_cache) try { - /* Cache base will be %esp plus cache->sp_offset (-8). */ + /* Cache base will be %rsp plus cache->sp_offset (-8). */ get_frame_register (this_frame, AMD64_RSP_REGNUM, buf); cache->base = extract_unsigned_integer (buf, 8, byte_order) + cache->sp_offset; /* Cache pc will be the frame func. */ - cache->pc = get_frame_pc (this_frame); + cache->pc = get_frame_func (this_frame); - /* The saved %esp will be at cache->base plus 16. */ + /* The previous value of %rsp is cache->base plus 16. */ cache->saved_sp = cache->base + 16; - /* The saved %eip will be at cache->base plus 8. */ + /* The saved %rip will be at cache->base plus 8. */ cache->saved_regs[AMD64_RIP_REGNUM] = cache->base + 8; cache->base_p = 1; @@ -2986,7 +2986,7 @@ amd64_epilogue_frame_this_id (frame_info_ptr this_frame, if (!cache->base_p) (*this_id) = frame_id_build_unavailable_stack (cache->pc); else - (*this_id) = frame_id_build (cache->base + 8, cache->pc); + (*this_id) = frame_id_build (cache->base + 16, cache->pc); } static const struct frame_unwind amd64_epilogue_frame_unwind = |