This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[ARM, commit+7.5] Fix watchpoint.exp failures


Hello,

some gdb.base/watchpoint.exp test were failing on ARM because 8-byte wide
watchpoint are not supported.  As a comment in the test case suggested,
I added ARM to a list of architectures where a fall-back to software
watchpoints is expected.

This still didn't work for remote targest, for two reasons:
- gdbserver would return "unsupported packet type" for watchpoints that
  couldn't be inserted due to length/alignment -- this confuses remote.c
- remote targets report failure to insert the watchpoint only at continue
  time -- the test case needed to be adapted to support this, just as is
  already done in other places in watchpoint.exp

With those changes, the test passes in both remote and native testing.

Tested on arm-linux-gnueabi (native & remote) with no regressions.
Committed to mainline and 7.5 branch.

Bye,
Ulrich


gdbserver/ChangeLog:

	* linux-arm-low.c (arm_linux_hw_point_initialize): Distinguish
	between unsupported TYPE and unimplementable ADDR/LEN combination.
	(arm_insert_point): Act on new return value.

testsuite/ChangeLog:

	* gdb.base/watchpoint.exp (test_wide_location_1): Expect software
	watchpoints on ARM.  When expecting software watchpoints, tolerate
	(remote) targets that report unsupported hardware watchpoint only
	at continue time.
	(test_wide_location_2): Likewise.


Index: gdb/gdbserver/linux-arm-low.c
===================================================================
RCS file: /cvs/src/src/gdb/gdbserver/linux-arm-low.c,v
retrieving revision 1.35
diff -u -p -r1.35 linux-arm-low.c
--- gdb/gdbserver/linux-arm-low.c	30 Jul 2012 15:05:43 -0000	1.35
+++ gdb/gdbserver/linux-arm-low.c	1 Aug 2012 12:57:56 -0000
@@ -432,8 +432,9 @@ arm_linux_hw_breakpoint_equal (const str
 
 /* Initialize the hardware breakpoint structure P for a breakpoint or
    watchpoint at ADDR to LEN.  The type of watchpoint is given in TYPE.
-   Returns -1 if TYPE is unsupported, 0 if TYPE represents a breakpoint,
-   and 1 if type represents a watchpoint.  */
+   Returns -1 if TYPE is unsupported, or -2 if the particular combination
+   of ADDR and LEN cannot be implemented.  Otherwise, returns 0 if TYPE
+   represents a breakpoint and 1 if type represents a watchpoint.  */
 static int
 arm_linux_hw_point_initialize (char type, CORE_ADDR addr, int len,
 			       struct arm_linux_hw_breakpoint *p)
@@ -483,7 +484,7 @@ arm_linux_hw_point_initialize (char type
 	  break;
 	default:
 	  /* Unsupported. */
-	  return -1;
+	  return -2;
 	}
     }
   else
@@ -493,17 +494,17 @@ arm_linux_hw_point_initialize (char type
 
       /* Can not set watchpoints for zero or negative lengths.  */
       if (len <= 0)
-	return -1;
+	return -2;
       /* The current ptrace interface can only handle watchpoints that are a
 	 power of 2.  */
       if ((len & (len - 1)) != 0)
-	return -1;
+	return -2;
 
       /* Test that the range [ADDR, ADDR + LEN) fits into the largest address
 	 range covered by a watchpoint.  */
       aligned_addr = addr & ~(max_wp_length - 1);
       if (aligned_addr + max_wp_length < addr + len)
-	return -1;
+	return -2;
 
       mask = (1 << len) - 1;
     }
@@ -560,7 +561,7 @@ arm_insert_point (char type, CORE_ADDR a
   if (watch < 0)
     {
       /* Unsupported.  */
-      return 1;
+      return watch == -1 ? 1 : -1;
     }
 
   if (watch)
Index: gdb/testsuite/gdb.base/watchpoint.exp
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.base/watchpoint.exp,v
retrieving revision 1.57
diff -u -p -r1.57 watchpoint.exp
--- gdb/testsuite/gdb.base/watchpoint.exp	21 Jun 2012 20:46:22 -0000	1.57
+++ gdb/testsuite/gdb.base/watchpoint.exp	1 Aug 2012 12:57:56 -0000
@@ -603,13 +603,15 @@ proc test_watch_location {} {
 
 proc test_wide_location_1 {} {
     global no_hw
+    global gdb_prompt
 
     # This test watches two words on most 32-bit ABIs, and one word on
     # most 64-bit ABIs.
 
     # Platforms where the target can't watch such a large region
     # should clear hw_expected below.
-    if { $no_hw || [target_info exists gdb,no_hardware_watchpoints] } {
+    if { $no_hw || [target_info exists gdb,no_hardware_watchpoints]
+         || [istarget arm*-*-*] } {
 	set hw_expected 0
     } else {
 	set hw_expected 1
@@ -625,9 +627,21 @@ proc test_wide_location_1 {} {
 	    "continue with watch foo2"
     } else {
 	gdb_test "watch foo2" "atchpoint .*: .*" "watch foo2"
-	gdb_test "continue" \
-	    "Continuing.*\[Ww\]atchpoint .*: .*New value = \\\{val = \\\{0, 11\\\}\\\}.*" \
-	    "continue with watch foo2"
+	set test "continue with watch foo2"
+	gdb_test_multiple "cont" $test {
+	    -re "Continuing.*\[Ww\]atchpoint .*: .*New value = \\\{val = \\\{0, 11\\\}\\\}.*$gdb_prompt $" {
+		pass $test
+	    }
+	    -re "Could not insert hardware breakpoints:.*You may have requested too many hardware breakpoints/watchpoints.*$gdb_prompt $" {
+		# This may happen with remote targets that support
+		# hardware watchpoints.  We only find out the
+		# watchpoint was too large, for example, at insert
+		# time.  If GDB is ever adjusted to downgrade the
+		# watchpoint automatically in this case, this match
+		# should be removed.
+		pass $test
+	    }
+	}
     }
 
     gdb_test_no_output "delete \$bpnum" "delete watch foo2"
@@ -635,13 +649,15 @@ proc test_wide_location_1 {} {
 
 proc test_wide_location_2 {} {
     global no_hw
+    global gdb_prompt
 
     # This test watches four words on most 32-bit ABIs, and two words
     # on 64-bit ABIs.
 
     # Platforms where the target can't watch such a large region
     # should clear hw_expected below.
-    if { $no_hw || [target_info exists gdb,no_hardware_watchpoints] } {
+    if { $no_hw || [target_info exists gdb,no_hardware_watchpoints]
+         || [istarget arm*-*-*] } {
 	set hw_expected 0
     } else {
 	set hw_expected 1
@@ -657,9 +673,21 @@ proc test_wide_location_2 {} {
 	    "continue with watch foo4"
     } else {
 	gdb_test "watch foo4" "atchpoint .*: .*" "watch foo4"
-	gdb_test "continue" \
-	    "Continuing.*\[Ww\]atchpoint .*: .*New value = \\\{val = \\\{0, 0, 0, 33\\\}\\\}.*" \
-	    "continue with watch foo4"
+	set test "continue with watch foo4"
+	gdb_test_multiple "cont" $test {
+	    -re "Continuing.*\[Ww\]atchpoint .*: .*New value = \\\{val = \\\{0, 0, 0, 33\\\}\\\}.*$gdb_prompt $" {
+		pass $test
+	    }
+	    -re "Could not insert hardware breakpoints:.*You may have requested too many hardware breakpoints/watchpoints.*$gdb_prompt $" {
+		# This may happen with remote targets that support
+		# hardware watchpoints.  We only find out the
+		# watchpoint was too large, for example, at insert
+		# time.  If GDB is ever adjusted to downgrade the
+		# watchpoint automatically in this case, this match
+		# should be removed.
+		pass $test
+	    }
+	}
     }
 
     gdb_test_no_output "delete \$bpnum" "delete watch foo4"
-- 
  Dr. Ulrich Weigand
  GNU Toolchain for Linux on System z and Cell BE
  Ulrich.Weigand@de.ibm.com


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]