From: Philippe Waroquiers Date: Wed, 3 Aug 2011 21:17:09 +0000 (+0000) Subject: 2011-08-03 Philippe Waroquiers X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=934709f0f26ebeaa5266669c45f8aa3d99b996a0;p=binutils-gdb.git 2011-08-03 Philippe Waroquiers * 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 * gdb.base/break-always.exp: Complete the test with duplicated breakpoints and enabling/disabling them. --- diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 6c5c594babe..358f5156482 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,12 @@ +2011-08-03 Philippe Waroquiers + + * 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 * stack.c (print_frame_arguments_choices): Comment typo fix. diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index e1c1a55787f..96d78ac173d 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -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 diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index fb9cac85986..6db2298172d 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2011-08-03 Philippe Waroquiers + + * gdb.base/break-always.exp: Complete the test + with duplicated breakpoints and enabling/disabling them. + 2011-08-02 Tom Tromey PR gdb/11289: diff --git a/gdb/testsuite/gdb.base/break-always.exp b/gdb/testsuite/gdb.base/break-always.exp index c6a46b11194..ce76af7c060 100644 --- a/gdb/testsuite/gdb.base/break-always.exp +++ b/gdb/testsuite/gdb.base/break-always.exp @@ -14,6 +14,8 @@ # along with this program. If not, see . # 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.*"