* breakpoint.c (compare_breakpoints): New function.
authorTom Tromey <tromey@redhat.com>
Fri, 9 Dec 2011 18:40:46 +0000 (18:40 +0000)
committerTom Tromey <tromey@redhat.com>
Fri, 9 Dec 2011 18:40:46 +0000 (18:40 +0000)
(clear_command): Remove duplicate breakpoints.  Properly clean
up.

gdb/ChangeLog
gdb/breakpoint.c

index 209f7b944782e8067628deb0d6222064e5ca46c9..9b7503bd05c4fc009d5d0a28603a62b0b002dc8d 100644 (file)
@@ -1,3 +1,9 @@
+2011-12-09  Tom Tromey  <tromey@redhat.com>
+
+       * breakpoint.c (compare_breakpoints): New function.
+       (clear_command): Remove duplicate breakpoints.  Properly clean
+       up.
+
 2011-12-08  Maciej W. Rozycki  <macro@mips.com>
             Maciej W. Rozycki  <macro@codesourcery.com>
 
index d9d5bbe5928d427b59c5f24a4608cf63606eca85..6f4f2d654db1e340415bee4efb1feeb04882085f 100644 (file)
@@ -10028,18 +10028,41 @@ tcatch_command (char *arg, int from_tty)
   error (_("Catch requires an event name."));
 }
 
+/* A qsort comparison function that sorts breakpoints in order.  */
+
+static int
+compare_breakpoints (const void *a, const void *b)
+{
+  const breakpoint_p *ba = a;
+  uintptr_t ua = (uintptr_t) *ba;
+  const breakpoint_p *bb = b;
+  uintptr_t ub = (uintptr_t) *bb;
+
+  if ((*ba)->number < (*bb)->number)
+    return -1;
+  else if ((*ba)->number > (*bb)->number)
+    return 1;
+
+  /* Now sort by address, in case we see, e..g, two breakpoints with
+     the number 0.  */
+  if (ua < ub)
+    return -1;
+  return ub > ub ? 1 : 0;
+}
+
 /* Delete breakpoints by address or line.  */
 
 static void
 clear_command (char *arg, int from_tty)
 {
-  struct breakpoint *b;
+  struct breakpoint *b, *prev;
   VEC(breakpoint_p) *found = 0;
   int ix;
   int default_match;
   struct symtabs_and_lines sals;
   struct symtab_and_line sal;
   int i;
+  struct cleanup *cleanups = make_cleanup (null_cleanup, NULL);
 
   if (arg)
     {
@@ -10090,6 +10113,7 @@ clear_command (char *arg, int from_tty)
      breakpoint.  */
 
   found = NULL;
+  make_cleanup (VEC_cleanup (breakpoint_p), &found);
   for (i = 0; i < sals.nelts; i++)
     {
       /* If exact pc given, clear bpts at that pc.
@@ -10143,6 +10167,7 @@ clear_command (char *arg, int from_tty)
            VEC_safe_push(breakpoint_p, found, b);
        }
     }
+
   /* Now go thru the 'found' chain and delete them.  */
   if (VEC_empty(breakpoint_p, found))
     {
@@ -10152,6 +10177,21 @@ clear_command (char *arg, int from_tty)
        error (_("No breakpoint at this line."));
     }
 
+  /* Remove duplicates from the vec.  */
+  qsort (VEC_address (breakpoint_p, found),
+        VEC_length (breakpoint_p, found),
+        sizeof (breakpoint_p),
+        compare_breakpoints);
+  prev = VEC_index (breakpoint_p, found, 0);
+  for (ix = 1; VEC_iterate (breakpoint_p, found, ix, b); ++ix)
+    {
+      if (b == prev)
+       {
+         VEC_ordered_remove (breakpoint_p, found, ix);
+         --ix;
+       }
+    }
+
   if (VEC_length(breakpoint_p, found) > 1)
     from_tty = 1;      /* Always report if deleted more than one.  */
   if (from_tty)
@@ -10171,6 +10211,8 @@ clear_command (char *arg, int from_tty)
     }
   if (from_tty)
     putchar_unfiltered ('\n');
+
+  do_cleanups (cleanups);
 }
 \f
 /* Delete breakpoint in BS if they are `delete' breakpoints and