This is the mail archive of the gdb-cvs@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[binutils-gdb] Insert breakpoint even when the raw breakpoint is found


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=20249ae4551ae7b2193caed73d9ce8d594f38754

commit 20249ae4551ae7b2193caed73d9ce8d594f38754
Author: Yao Qi <yao.qi@linaro.org>
Date:   Mon Apr 25 09:43:36 2016 +0100

    Insert breakpoint even when the raw breakpoint is found
    
    When GDBserver inserts a breakpoint, it looks for raw breakpoint, if
    the raw breakpoint is found, increase its refcount, and return.  This
    doesn't work when it steps over a breakpoint using software single
    step and the underneath instruction of breakpoint is branch to self.
    
    When stepping over a breakpoint on ADDR using software single step,
    GDBserver uninsert the breakpoint, so the corresponding raw breakpoint
    RAW's 'inserted' flag is zero.  Then, GDBserver insert single step
    breakpoint at the same address ADDR because the instruction is branch
    to self, the same raw brekapoint RAW is found, and increase the
    refcount.  However, the raw breakpoint is not inserted, and the
    program won't stop.
    
    gdb/gdbserver:
    
    2016-04-25  Pedro Alves  <palves@redhat.com>
    	    Yao Qi  <yao.qi@linaro.org>
    
    	* mem-break.c (set_raw_breakpoint_at): Create a raw breakpoint
    	object.  Insert it if it is not inserted yet.  Increase the
    	refcount and link it into the proc's raw breakpoint list.

Diff:
---
 gdb/ChangeLog             |  7 +++++++
 gdb/gdbserver/mem-break.c | 48 +++++++++++++++++++++++++++--------------------
 2 files changed, 35 insertions(+), 20 deletions(-)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 0b08605..5c94832 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,10 @@
+2016-04-25  Pedro Alves  <palves@redhat.com>
+	    Yao Qi  <yao.qi@linaro.org>
+
+	* mem-break.c (set_raw_breakpoint_at): Create a raw breakpoint
+	object.  Insert it if it is not inserted yet.  Increase the
+	refcount and link it into the proc's raw breakpoint list.
+
 2016-04-25  Yao Qi  <yao.qi@linaro.org>
 
 	* breakpoint.c (should_be_inserted): Return 0 if the location's
diff --git a/gdb/gdbserver/mem-break.c b/gdb/gdbserver/mem-break.c
index b06f8e9..419db9e 100644
--- a/gdb/gdbserver/mem-break.c
+++ b/gdb/gdbserver/mem-break.c
@@ -390,6 +390,7 @@ set_raw_breakpoint_at (enum raw_bkpt_type type, CORE_ADDR where, int kind,
 {
   struct process_info *proc = current_process ();
   struct raw_breakpoint *bp;
+  struct cleanup *old_chain = make_cleanup (null_cleanup, NULL);
 
   if (type == raw_bkpt_type_sw || type == raw_bkpt_type_hw)
     {
@@ -408,32 +409,39 @@ set_raw_breakpoint_at (enum raw_bkpt_type type, CORE_ADDR where, int kind,
   else
     bp = find_raw_breakpoint_at (where, type, kind);
 
-  if (bp != NULL)
+  if (bp == NULL)
     {
-      bp->refcount++;
-      return bp;
+      bp = XCNEW (struct raw_breakpoint);
+      bp->pc = where;
+      bp->kind = kind;
+      bp->raw_type = type;
+      make_cleanup (xfree, bp);
     }
 
-  bp = XCNEW (struct raw_breakpoint);
-  bp->pc = where;
-  bp->kind = kind;
-  bp->refcount = 1;
-  bp->raw_type = type;
-
-  *err = the_target->insert_point (bp->raw_type, bp->pc, bp->kind, bp);
-  if (*err != 0)
+  if (!bp->inserted)
     {
-      if (debug_threads)
-	debug_printf ("Failed to insert breakpoint at 0x%s (%d).\n",
-		      paddress (where), *err);
-      free (bp);
-      return NULL;
+      *err = the_target->insert_point (bp->raw_type, bp->pc, bp->kind, bp);
+      if (*err != 0)
+	{
+	  if (debug_threads)
+	    debug_printf ("Failed to insert breakpoint at 0x%s (%d).\n",
+			  paddress (where), *err);
+
+	  do_cleanups (old_chain);
+	  return NULL;
+	}
+
+      bp->inserted = 1;
     }
 
-  bp->inserted = 1;
-  /* Link the breakpoint in.  */
-  bp->next = proc->raw_breakpoints;
-  proc->raw_breakpoints = bp;
+  discard_cleanups (old_chain);
+
+  /* Link the breakpoint in, if this is the first reference.  */
+  if (++bp->refcount == 1)
+    {
+      bp->next = proc->raw_breakpoints;
+      proc->raw_breakpoints = bp;
+    }
   return bp;
 }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]