Get frame after pull single-step breakpoints out

Message ID 1396505398-23634-1-git-send-email-yao@codesourcery.com
State Superseded
Headers

Commit Message

Yao Qi April 3, 2014, 6:09 a.m. UTC
  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(-)
  

Patch

diff --git a/gdb/infrun.c b/gdb/infrun.c
index 31bb132..a641a6e 100644
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -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