Get frame after pull single-step breakpoints out
Commit Message
Hi,
I find that instruction that red by signal trampoline unwinder sniffer
is always the breakpoint instruction. I suspect that GDB tries to get
frame before pulls breakpoint out of the target. The backtrace is
like:
#0 tramp_frame_sniffer () at gdb/tramp-frame.c:135
#1 frame_unwind_try_unwinder () at gdb/frame-unwind.c:108
.....
.....
#13 get_current_frame () at gdb/frame.c:1480
#14 handle_signal_stop () at gdb/infrun.c:3971
In infrun.c:handle_signal_stop,
/* At this point, get hold of the now-current thread's frame. */
frame = get_current_frame ();
gdbarch = get_frame_arch (frame);
/* Pull the single step breakpoints out of the target. */
if (singlestep_breakpoints_inserted_p)
we can see GDB gets frame before pulling single-step breakpoint out,
that is the reason why trampoline unwinder reads breakpoint
instruction. I find this problem on nios2-linux, but it should affect
software single step targets (I don't see these fails in
arm-linux-gnu-eabi, because signal trampoline frame is created when PC
is still in function keeper, so although breakpoint instruction isn't
pulled out of the inferior, instructions in signal trampoline are not
changed).
This patch is to exchange the order of getting frame and pulling out
breakpoints, so trampoline frame unwinder can read the real instruction
rather than breakpoint instruction. This patch fixes these fails on
nios2-linux target:
FAIL: gdb.base/sigbpt.exp: stepi; stepi out of handler
FAIL: gdb.base/sigbpt.exp: stepi bp before segv; stepi out of handler
FAIL: gdb.base/sigbpt.exp: stepi bp at segv; stepi out of handler
FAIL: gdb.base/sigbpt.exp: stepi bp before and at segv; stepi out of handler
FAIL: gdb.base/siginfo.exp: step out of handler
FAIL: gdb.base/sigstep.exp: step from handler; leave handler
FAIL: gdb.base/sigstep.exp: stepi from handleri; leave handler
FAIL: gdb.base/sigstep.exp: stepi from handleri; leave signal trampoline
FAIL: gdb.base/sigstep.exp: next from handler; leave handler
FAIL: gdb.base/sigstep.exp: nexti from handleri; leave handler
FAIL: gdb.base/sigstep.exp: nexti from handleri; leave signal trampoline
gdb:
2014-04-03 Yao Qi <yao@codesourcery.com>
* infrun.c (handle_signal_stop): Exchange code on getting
frame and pulling single-step breakpoints out.
---
gdb/infrun.c | 8 ++++----
1 files changed, 4 insertions(+), 4 deletions(-)
@@ -3941,10 +3941,6 @@ handle_signal_stop (struct execution_control_state *ecs)
deprecated_context_hook (pid_to_thread_id (ecs->ptid));
}
- /* At this point, get hold of the now-current thread's frame. */
- frame = get_current_frame ();
- gdbarch = get_frame_arch (frame);
-
/* Pull the single step breakpoints out of the target. */
if (singlestep_breakpoints_inserted_p)
{
@@ -3979,6 +3975,10 @@ handle_signal_stop (struct execution_control_state *ecs)
singlestep_breakpoints_inserted_p = 0;
}
+ /* At this point, get hold of the now-current thread's frame. */
+ frame = get_current_frame ();
+ gdbarch = get_frame_arch (frame);
+
if (ecs->stepped_after_stopped_by_watchpoint)
stopped_by_watchpoint = 0;
else