[PATCH] Failure to stop at duplicate breakpoints

Andrew Burgess aburgess@broadcom.com
Thu Sep 20 15:10:00 GMT 2012


When two breakpoints are created at the same location, one of them is 
marked as a duplicate.  When gdb inserts the breakpoints we only really 
insert one breakpoint at any unique location.

By creating duplicate breakpoints and deleting or disabling them in the 
right order it is possible to get into a state where gdb has a single 
breakpoint with a single location, but that location is marked duplicate 
and so is never inserted, with the result we don't stop at the breakpoint.

Patch and test included below.

OK to apply?

Thanks
Andrew

gdb/ChangeLog

2012-09-20  Andrew Burgess  <aburgess@broadcom.com>

	* breakpoint.c (update_global_location_list): Ignore previous
	duplicate status of a breakpoint when starting a new scan for
	duplicate breakpoints.

diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index b841bcd..f771d06 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -12463,7 +12463,7 @@ update_global_location_list (int should_insert)
        struct bp_location **loc_first_p;
        b = loc->owner;

-      if (!should_be_inserted (loc)
+      if (!unduplicated_should_be_inserted (loc)
           || !breakpoint_address_is_meaningful (b)
           /* Don't detect duplicate for tracepoint locations because 
they are
            never duplicated.  See the comments in field `duplicate' of

gdb/testsuite/ChangeLog

2012-09-20  Andrew Burgess  <aburgess@broadcom.com>

	* gdb.base/duplicate-bp.c: New file.
	* gdb.base/duplicate-bp.exp: New file.

diff --git a/gdb/testsuite/gdb.base/duplicate-bp.c 
b/gdb/testsuite/gdb.base/duplicate-bp.c
new file mode 100644
index 0000000..50145b4
--- /dev/null
+++ b/gdb/testsuite/gdb.base/duplicate-bp.c
@@ -0,0 +1,23 @@
+void
+spacer ()
+{
+  /* Nothing.  */
+}
+
+void
+breakpt ()
+{
+  /* Nothing.  */
+}
+
+int
+main ()
+{
+  spacer ();
+
+  breakpt ();
+
+  spacer ();
+
+  return 0;
+}
diff --git a/gdb/testsuite/gdb.base/duplicate-bp.exp 
b/gdb/testsuite/gdb.base/duplicate-bp.exp
new file mode 100644
index 0000000..021aa30
--- /dev/null
+++ b/gdb/testsuite/gdb.base/duplicate-bp.exp
@@ -0,0 +1,137 @@
+# Copyright 2012 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+if { [prepare_for_testing duplicate-bp.exp "duplicate-bp" 
{duplicate-bp.c} {debug nowarnings}] } {
+    return -1
+}
+set srcfile "duplicate-bp.c"
+
+# Setup for the test, create COUNT breakpoints at the function BREAKPT.
+proc test_setup { count } {
+    upvar srcfile srcfile
+
+    clean_restart duplicate-bp
+
+    if ![runto_main] then {
+	fail "can't run to main"
+	return 0
+    }
+
+    for {set i 1} {$i <= $count} {incr i} {
+	gdb_breakpoint "breakpt"
+	gdb_test_no_output "set \$bp_num_${i} = \$bpnum"
+    }
+
+    gdb_test "step" "spacer \\(\\) at .*$srcfile:\[0-9\]+.*"
+
+    return 1
+}
+
+
+# Test 1: Create two breakpoints at BREAKPT.  Delete #1 and expect to stop
+# at #2.
+test_setup 2
+
+gdb_test_no_output {delete $bp_num_1}
+
+gdb_test continue "Continuing\\..*Breakpoint \[0-9\]+, breakpt \\(\\) 
at .*$srcfile:\[0-9\]+.*" \
+			"delete #1, stop at #2"
+
+# Test 2: Create two breakpoints at BREAKPT.  Delete #2 and expect to stop
+# at #1.
+test_setup 2
+
+gdb_test_no_output {delete $bp_num_2}
+
+gdb_test continue "Continuing\\..*Breakpoint \[0-9\]+, breakpt \\(\\) 
at .*$srcfile:\[0-9\]+.*" \
+			"delete #2, stop at #1"
+
+# Test 3: Create three breakpoints at BREAKPT.  Disable #1, delete #2,
+# expect to stop at #3.
+test_setup 3
+
+gdb_test_no_output {disable $bp_num_1}
+
+gdb_test "step" ".*"
+
+gdb_test_no_output {delete $bp_num_2}
+
+gdb_test continue "Continuing\\..*Breakpoint \[0-9\]+, breakpt \\(\\) 
at .*$srcfile:\[0-9\]+.*" \
+			"disable #1, delete #2, stop at #3"
+
+# Test 4: Create three breakpoints at BREAKPT.  Disable #2, delete #1,
+# expect to stop at #3.
+test_setup 3
+
+gdb_test_no_output {disable $bp_num_2}
+
+gdb_test "step" ".*"
+
+gdb_test_no_output {delete $bp_num_1}
+
+gdb_test continue "Continuing\\..*Breakpoint \[0-9\]+, breakpt \\(\\) 
at .*$srcfile:\[0-9\]+.*" \
+			"disable #2, delete #1, stop at #3"
+
+# Test 5: Create three breakpoints at BREAKPT.  Disable #1, delete #3,
+# expect to stop at #1.
+test_setup 3
+
+gdb_test_no_output {disable $bp_num_1}
+
+gdb_test "step" ".*"
+
+gdb_test_no_output {delete $bp_num_3}
+
+gdb_test continue "Continuing\\..*Breakpoint \[0-9\]+, breakpt \\(\\) 
at .*$srcfile:\[0-9\]+.*" \
+			"disable #1, delete #3, stop at #1"
+
+# Test 6: Create three breakpoints at BREAKPT.  Disable #3, delete #1,
+# expect to stop at #2.
+test_setup 3
+
+gdb_test_no_output {disable $bp_num_3}
+
+gdb_test "step" ".*"
+
+gdb_test_no_output {delete $bp_num_1}
+
+gdb_test continue "Continuing\\..*Breakpoint \[0-9\]+, breakpt \\(\\) 
at .*$srcfile:\[0-9\]+.*" \
+			"disable #3, delete #1, stop at #2"
+
+# Test 7: Create three breakpoints at BREAKPT.  Disable #2, delete #3,
+# expect to stop at #1.
+test_setup 3
+
+gdb_test_no_output {disable $bp_num_2}
+
+gdb_test "step" ".*"
+
+gdb_test_no_output {delete $bp_num_3}
+
+gdb_test continue "Continuing\\..*Breakpoint \[0-9\]+, breakpt \\(\\) 
at .*$srcfile:\[0-9\]+.*" \
+			"disable #2, delete #3, stop at #1"
+
+# Test 6: Create three breakpoints at BREAKPT.  Disable #3, delete #2,
+# expect to stop at #1.
+test_setup 3
+
+gdb_test_no_output {disable $bp_num_3}
+
+gdb_test "step" ".*"
+
+gdb_test_no_output {delete $bp_num_2}
+
+gdb_test continue "Continuing\\..*Breakpoint \[0-9\]+, breakpt \\(\\) 
at .*$srcfile:\[0-9\]+.*" \
+			"disable #3, delete #2, stop at #1"





More information about the Gdb-patches mailing list