[pushed] gdbserver: redo stepping over breakpoint that was on top of a permanent breakpoint

Message ID 86wpvg7y22.fsf@gmail.com
State New, archived
Headers

Commit Message

Yao Qi Sept. 24, 2015, 1:21 p.m. UTC
  Antoine Tremblay <antoine.tremblay@ericsson.com> writes:

> Indeed I have a fix for this see :
> https://sourceware.org/ml/gdb-patches/2015-09/msg00222.html
>

Ah, I did read your patch, but I forget it when I am fixing this problem.

> But I thought it would not trigger until conditional breakpoints are
> implemented thus I had not included it in this patchset.
>
> Could you share how exactly you get GDBServer to insert an internal
> breakpoint, I'm unfamiliar with :  "I force GDBserver to use thread
> event breakpoint" ?

It can be triggered when GDBserver steps over its breakpoints, what I
did is to pass 1 to thread_db_init, so that GDBserver will insert
breakpoint on __nptl_create_event.  Once a new thread is created, and
hits this breakpoint, GDBserver will step over this breakpoint.
  

Comments

Antoine Tremblay Sept. 24, 2015, 4:43 p.m. UTC | #1
On 09/24/2015 09:21 AM, Yao Qi wrote:
> Antoine Tremblay <antoine.tremblay@ericsson.com> writes:
>
>> Indeed I have a fix for this see :
>> https://sourceware.org/ml/gdb-patches/2015-09/msg00222.html
>>
>
> Ah, I did read your patch, but I forget it when I am fixing this problem.
>

Np, I think that patch is valid with the scenario you mention below, 
however since it won't work properly as reinsert_addr doesn't work at 
this stage I think it may be better to introduce it when I post the 
single stepping support ?

> It can be triggered when GDBserver steps over its breakpoints, what I
> did is to pass 1 to thread_db_init, so that GDBserver will insert
> breakpoint on __nptl_create_event.  Once a new thread is created, and
> hits this breakpoint, GDBserver will step over this breakpoint.
>

Haa I had missed that scenario!

>--- a/gdb/gdbserver/linux-low.c
+++ b/gdb/gdbserver/linux-low.c
@@ -3010,7 +3010,8 @@ linux_wait_1 (ptid_t ptid,
       Advance the PC manually past the breakpoint, otherwise the
       program would keep trapping the permanent breakpoint forever.  */
    if (!ptid_equal (step_over_bkpt, null_ptid)
-      && event_child->stop_reason == TARGET_STOPPED_BY_SW_BREAKPOINT)
+      && event_child->stop_reason == TARGET_STOPPED_BY_SW_BREAKPOINT
+      && gdb_breakpoint_here (event_child->stop_pc))
      {
        int increment_pc = 0;
        CORE_ADDR stop_pc = event_child->stop_pc;

This won't work as that single step breakpoint is not a gdb breakpoint 
we need to check for a reinsert breakpoint like the patch I mentioned.

I tested the scenario with my patch and the issue is solved.

Note however I'm a bit concerted about the hack to remote_check_symbols. 
  I need to dig into it to understand that one should we expect it to 
work without this hack ?
  

Patch

diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c
index 9fb83a8..0d88694 100644
--- a/gdb/gdbserver/linux-low.c
+++ b/gdb/gdbserver/linux-low.c
@@ -5501,7 +5501,7 @@  linux_look_up_symbols (void)
   /* If the kernel supports tracing clones, then we don't need to
      use the magic thread event breakpoint to learn about
      threads.  */
-  thread_db_init (!linux_supports_traceclone ());
+  thread_db_init (1/*!linux_supports_traceclone ()*/);
 #endif
 }
 
diff --git a/gdb/remote.c b/gdb/remote.c
index b9dc4af..f1dec19 100644
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -4157,6 +4157,13 @@  remote_check_symbols (void)
 							 sym_addr,
 							 &current_target);
 
+	  /* Hack for arm gdbserver when the thread library is compiled in
+	     thumb mode.  Set the LSB of address of __nptl_create_event so
+	     that GDBserver can choose the right breakpoint instruction to
+	     set on it.  */
+	  if (strcmp ("__nptl_create_event", msg) == 0)
+	    sym_addr |= 1;
+
 	  xsnprintf (msg, get_remote_packet_size (), "qSymbol:%s:%s",
 		     phex_nz (sym_addr, addr_size), &reply[8]);
 	}