2011-08-03 Philippe Waroquiers <philippe.waroquiers@skynet.be>
authorPhilippe Waroquiers <philippe@sourceware.org>
Wed, 3 Aug 2011 21:17:09 +0000 (21:17 +0000)
committerPhilippe Waroquiers <philippe@sourceware.org>
Wed, 3 Aug 2011 21:17:09 +0000 (21:17 +0000)
* breakpoint.c (update_global_location_list): Ensure
invariant 'first loc marked not duplicated and inserted,
following locs marked duplicated/not inserted' is respected
for multiple locations at the same address.
(unduplicated_should_be_inserted) New function.
(swap_insertion) New function.

2011-08-03  Philippe Waroquiers  <philippe.waroquiers@skynet.be>

* gdb.base/break-always.exp: Complete the test
with duplicated breakpoints and enabling/disabling them.

gdb/ChangeLog
gdb/breakpoint.c
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.base/break-always.exp

index 6c5c594babeb9a3cfc837becdf809c478695eb21..358f51564826f9328fb686f67a78acc560ca12a0 100644 (file)
@@ -1,3 +1,12 @@
+2011-08-03  Philippe Waroquiers  <philippe.waroquiers@skynet.be>
+
+       * breakpoint.c (update_global_location_list): Ensure
+       invariant 'first loc marked not duplicated and inserted,
+       following locs marked duplicated/not inserted' is respected
+       for multiple locations at the same address.
+       (unduplicated_should_be_inserted) New function.
+       (swap_insertion) New function.
+
 2011-08-03  Jan Kratochvil  <jan.kratochvil@redhat.com>
 
        * stack.c (print_frame_arguments_choices): Comment typo fix.
index e1c1a55787f1ad0eae456b11a3888ed2ace0ab6e..96d78ac173ded966aa14803343085307b8408ec5 100644 (file)
@@ -1571,6 +1571,21 @@ should_be_inserted (struct bp_location *bl)
   return 1;
 }
 
+/* Same as should_be_inserted but does the check assuming
+   that the location is not duplicated.  */
+
+static int
+unduplicated_should_be_inserted (struct bp_location *bl)
+{
+  int result;
+  const int save_duplicate = bl->duplicate;
+
+  bl->duplicate = 0;
+  result = should_be_inserted (bl);
+  bl->duplicate = save_duplicate;
+  return result;
+}
+
 /* Insert a low-level "breakpoint" of some type.  BL is the breakpoint
    location.  Any error messages are printed to TMP_ERROR_STREAM; and
    DISABLED_BREAKS, and HW_BREAKPOINT_ERROR are used to report problems.
@@ -10241,6 +10256,23 @@ bp_location_target_extensions_update (void)
     }
 }
 
+/* Swap the insertion/duplication state between two locations.  */
+
+static void
+swap_insertion (struct bp_location *left, struct bp_location *right)
+{
+  const int left_inserted = left->inserted;
+  const int left_duplicate = left->duplicate;
+  const struct bp_target_info left_target_info = left->target_info;
+
+  left->inserted = right->inserted;
+  left->duplicate = right->duplicate;
+  left->target_info = right->target_info;
+  right->inserted = left_inserted;
+  right->duplicate = left_duplicate;
+  right->target_info = left_target_info;
+}
+
 /* If SHOULD_INSERT is false, do not insert any breakpoint locations
    into the inferior, only remove already-inserted locations that no
    longer should be inserted.  Functions that delete a breakpoint or
@@ -10377,11 +10409,6 @@ update_global_location_list (int should_insert)
 
                      if (breakpoint_locations_match (loc2, old_loc))
                        {
-                         /* For the sake of should_be_inserted.
-                            Duplicates check below will fix up this
-                            later.  */
-                         loc2->duplicate = 0;
-
                          /* Read watchpoint locations are switched to
                             access watchpoints, if the former are not
                             supported, but the latter are.  */
@@ -10391,10 +10418,13 @@ update_global_location_list (int should_insert)
                              loc2->watchpoint_type = old_loc->watchpoint_type;
                            }
 
-                         if (loc2 != old_loc && should_be_inserted (loc2))
+                         /* loc2 is a duplicated location. We need to check
+                            if it should be inserted in case it will be
+                            unduplicated.  */
+                         if (loc2 != old_loc
+                             && unduplicated_should_be_inserted (loc2))
                            {
-                             loc2->inserted = 1;
-                             loc2->target_info = old_loc->target_info;
+                             swap_insertion (old_loc, loc2);
                              keep_in_target = 1;
                              break;
                            }
@@ -10541,6 +10571,12 @@ update_global_location_list (int should_insert)
          continue;
        }
 
+
+      /* This and the above ensure the invariant that the first location
+        is not duplicated, and is the inserted one.
+        All following are marked as duplicated, and are not inserted.  */
+      if (loc->inserted)
+       swap_insertion (loc, *loc_first_p);
       loc->duplicate = 1;
 
       if ((*loc_first_p)->owner->enable_state == bp_permanent && loc->inserted
index fb9cac85986e17e7731d2139f5a44f89dd8b8ef4..6db2298172d23007187adcac8baca17e4f75c64d 100644 (file)
@@ -1,3 +1,8 @@
+2011-08-03  Philippe Waroquiers  <philippe.waroquiers@skynet.be>
+
+       * gdb.base/break-always.exp: Complete the test
+       with duplicated breakpoints and enabling/disabling them.
+
 2011-08-02  Tom Tromey  <tromey@redhat.com>
 
        PR gdb/11289:
index c6a46b111940e2ebc5d5bb53fdea57bbc0a9f7bb..ce76af7c06076e35c35cb4d3f835e3745b0e974e 100644 (file)
@@ -14,6 +14,8 @@
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 # Test that 'set breakpoint always-inserted 1' is not a brick
+# Also verifies that breakpoint enabling/disabling works properly
+# with duplicated breakpoints.
 
 if { [prepare_for_testing break-always.exp break-always break-always.c] } {
     return -1
@@ -29,6 +31,24 @@ gdb_test "show breakpoint always-inserted" "mode is on\." \
 runto foo
 
 gdb_test "break bar" "Breakpoint 2.*" "set breakpoint on bar"
+gdb_test "break bar" "Note: breakpoint 2 also set.*Breakpoint 3.*" "set 2nd breakpoint on bar"
+gdb_test "break bar" "Note: breakpoints 2 and 3 also set.*Breakpoint 4.*" "set 3rd breakpoint on bar"
+gdb_test "break bar" "Note: breakpoints 2, 3 and 4 also set.*Breakpoint 5.*" "set 4th breakpoint on bar"
+gdb_test "info breakpoints" "keep y.*keep y.*keep y.*keep y.*keep y.*" "initial check breakpoint state"
+gdb_test_no_output "disable" "initial disable all breakpoints"
+gdb_test_no_output "enable" "initial enable all breakpoints"
+gdb_test_no_output "disable" "re-disable all breakpoints"
+gdb_test_no_output "enable 3" "enable 3.A"
+gdb_test_no_output "disable 3" "disable 3.B"
+gdb_test_no_output "enable 3" "enable 3.C"
+gdb_test_no_output "enable 2" "enable 2.D"
+gdb_test_no_output "disable 2" "disable 2.E"
+gdb_test_no_output "disable 3" "disable 3.F"
+gdb_test_no_output "enable 3" "enable 3.G"
+gdb_test_no_output "enable 2" "enable 2.H"
+gdb_test_no_output "disable 2" "disable 2.I"
+gdb_test "info breakpoints" "keep n.*keep n.*keep y.*keep n.*keep n.*" "before re-enable check breakpoint state"
+gdb_test_no_output "enable" "re-enable all breakpoints"
 gdb_continue_to_breakpoint "bar" ".*break-always.c:$bar_location.*"