Skip gdb.server/ tests if lack of XML support
[deliverable/binutils-gdb.git] / gdb / gdbserver / mem-break.c
index b06f8e96ecc02efb120afdded79d45f6726ea4f6..5c73326ebb547a5c93bbae09ca4011c1a0ecd182 100644 (file)
@@ -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;
 }
 
@@ -1501,13 +1509,33 @@ uninsert_all_breakpoints (void)
       uninsert_raw_breakpoint (bp);
 }
 
+void
+uninsert_reinsert_breakpoints (void)
+{
+  struct process_info *proc = current_process ();
+  struct breakpoint *bp;
+
+  for (bp = proc->breakpoints; bp != NULL; bp = bp->next)
+    {
+    if (bp->type == reinsert_breakpoint)
+      {
+       gdb_assert (bp->raw->inserted > 0);
+
+       /* Only uninsert the raw breakpoint if it only belongs to a
+          reinsert breakpoint.  */
+       if (bp->raw->refcount == 1)
+         uninsert_raw_breakpoint (bp->raw);
+      }
+    }
+}
+
 static void
 reinsert_raw_breakpoint (struct raw_breakpoint *bp)
 {
   int err;
 
   if (bp->inserted)
-    error ("Breakpoint already inserted at reinsert time.");
+    return;
 
   err = the_target->insert_point (bp->raw_type, bp->pc, bp->kind, bp);
   if (err == 0)
@@ -1545,6 +1573,28 @@ reinsert_breakpoints_at (CORE_ADDR pc)
     }
 }
 
+int
+has_reinsert_breakpoints (struct process_info *proc)
+{
+  struct breakpoint *bp, **bp_link;
+
+  bp = proc->breakpoints;
+  bp_link = &proc->breakpoints;
+
+  while (bp)
+    {
+      if (bp->type == reinsert_breakpoint)
+       return 1;
+      else
+       {
+         bp_link = &bp->next;
+         bp = *bp_link;
+       }
+    }
+
+  return 0;
+}
+
 void
 reinsert_all_breakpoints (void)
 {
@@ -1558,6 +1608,24 @@ reinsert_all_breakpoints (void)
       reinsert_raw_breakpoint (bp);
 }
 
+void
+reinsert_reinsert_breakpoints (void)
+{
+  struct process_info *proc = current_process ();
+  struct breakpoint *bp;
+
+  for (bp = proc->breakpoints; bp != NULL; bp = bp->next)
+    {
+      if (bp->type == reinsert_breakpoint)
+       {
+         gdb_assert (bp->raw->inserted > 0);
+
+         if (bp->raw->refcount == 1)
+           reinsert_raw_breakpoint (bp->raw);
+       }
+    }
+}
+
 void
 check_breakpoints (CORE_ADDR stop_pc)
 {
@@ -1710,7 +1778,12 @@ delete_disabled_breakpoints (void)
     {
       next = bp->next;
       if (bp->raw->inserted < 0)
-       delete_breakpoint_1 (proc, bp);
+       {
+         /* If reinsert_breakpoints become disabled, that means the
+            manipulations (insertion and removal) of them are wrong.  */
+         gdb_assert (bp->type != reinsert_breakpoint);
+         delete_breakpoint_1 (proc, bp);
+       }
     }
 }
 
This page took 0.027543 seconds and 4 git commands to generate.