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]

RFC: Relax checking of garbage struct return values


The comments are supposed to have the story.  Tested on
x86_64-pc-linux-gnu.

2005-10-05  Jim Blandy  <jimb@redhat.com>

	* gdb.base/structs.exp (any): New function.
	(test_struct_returns): Don't make any assumptions at all about
	what value the function returns when GDB can't set the return
	value.
	
Index: gdb/testsuite/gdb.base/structs.exp
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.base/structs.exp,v
retrieving revision 1.21
diff -c -p -r1.21 structs.exp
*** gdb/testsuite/gdb.base/structs.exp	10 Jun 2004 21:38:03 -0000	1.21
--- gdb/testsuite/gdb.base/structs.exp	6 Oct 2005 17:41:49 -0000
*************** proc zed { n } {
*** 162,167 ****
--- 162,190 ----
      } $n]
  }
  
+ proc any { n } {
+     return [lindex {
+ 	"{}"
+ 	"{a = \[^,\}\]*}"
+ 	"{a = \[^,\}\]*, b = \[^,\}\]*}"
+ 	"{a = \[^,\}\]*, b = \[^,\}\]*, c = \[^,\}\]*}"
+ 	"{a = \[^,\}\]*, b = \[^,\}\]*, c = \[^,\}\]*, d = \[^,\}\]*}"
+ 	"{a = \[^,\}\]*, b = \[^,\}\]*, c = \[^,\}\]*, d = \[^,\}\]*, e = \[^,\}\]*}"
+ 	"{a = \[^,\}\]*, b = \[^,\}\]*, c = \[^,\}\]*, d = \[^,\}\]*, e = \[^,\}\]*, f = \[^,\}\]*}"
+ 	"{a = \[^,\}\]*, b = \[^,\}\]*, c = \[^,\}\]*, d = \[^,\}\]*, e = \[^,\}\]*, f = \[^,\}\]*, g = \[^,\}\]*}"
+ 	"{a = \[^,\}\]*, b = \[^,\}\]*, c = \[^,\}\]*, d = \[^,\}\]*, e = \[^,\}\]*, f = \[^,\}\]*, g = \[^,\}\]*, h = \[^,\}\]*}"
+ 	"{a = \[^,\}\]*, b = \[^,\}\]*, c = \[^,\}\]*, d = \[^,\}\]*, e = \[^,\}\]*, f = \[^,\}\]*, g = \[^,\}\]*, h = \[^,\}\]*, i = \[^,\}\]*}"
+ 	"{a = \[^,\}\]*, b = \[^,\}\]*, c = \[^,\}\]*, d = \[^,\}\]*, e = \[^,\}\]*, f = \[^,\}\]*, g = \[^,\}\]*, h = \[^,\}\]*, i = \[^,\}\]*, j = \[^,\}\]*}"
+ 	"{a = \[^,\}\]*, b = \[^,\}\]*, c = \[^,\}\]*, d = \[^,\}\]*, e = \[^,\}\]*, f = \[^,\}\]*, g = \[^,\}\]*, h = \[^,\}\]*, i = \[^,\}\]*, j = \[^,\}\]*, k = \[^,\}\]*}"
+ 	"{a = \[^,\}\]*, b = \[^,\}\]*, c = \[^,\}\]*, d = \[^,\}\]*, e = \[^,\}\]*, f = \[^,\}\]*, g = \[^,\}\]*, h = \[^,\}\]*, i = \[^,\}\]*, j = \[^,\}\]*, k = \[^,\}\]*, l = \[^,\}\]*}"
+ 	"{a = \[^,\}\]*, b = \[^,\}\]*, c = \[^,\}\]*, d = \[^,\}\]*, e = \[^,\}\]*, f = \[^,\}\]*, g = \[^,\}\]*, h = \[^,\}\]*, i = \[^,\}\]*, j = \[^,\}\]*, k = \[^,\}\]*, l = \[^,\}\]*, m = \[^,\}\]*}"
+ 	"{a = \[^,\}\]*, b = \[^,\}\]*, c = \[^,\}\]*, d = \[^,\}\]*, e = \[^,\}\]*, f = \[^,\}\]*, g = \[^,\}\]*, h = \[^,\}\]*, i = \[^,\}\]*, j = \[^,\}\]*, k = \[^,\}\]*, l = \[^,\}\]*, m = \[^,\}\]*, n = \[^,\}\]*}"
+ 	"{a = \[^,\}\]*, b = \[^,\}\]*, c = \[^,\}\]*, d = \[^,\}\]*, e = \[^,\}\]*, f = \[^,\}\]*, g = \[^,\}\]*, h = \[^,\}\]*, i = \[^,\}\]*, j = \[^,\}\]*, k = \[^,\}\]*, l = \[^,\}\]*, m = \[^,\}\]*, n = \[^,\}\]*, o = \[^,\}\]*}"
+ 	"{a = \[^,\}\]*, b = \[^,\}\]*, c = \[^,\}\]*, d = \[^,\}\]*, e = \[^,\}\]*, f = \[^,\}\]*, g = \[^,\}\]*, h = \[^,\}\]*, i = \[^,\}\]*, j = \[^,\}\]*, k = \[^,\}\]*, l = \[^,\}\]*, m = \[^,\}\]*, n = \[^,\}\]*, o = \[^,\}\]*, p = \[^,\}\]*}"
+ 	"{a = \[^,\}\]*, b = \[^,\}\]*, c = \[^,\}\]*, d = \[^,\}\]*, e = \[^,\}\]*, f = \[^,\}\]*, g = \[^,\}\]*, h = \[^,\}\]*, i = \[^,\}\]*, j = \[^,\}\]*, k = \[^,\}\]*, l = \[^,\}\]*, m = \[^,\}\]*, n = \[^,\}\]*, o = \[^,\}\]*, p = \[^,\}\]*, q = \[^,\}\]*}"
+     } $n]
+ }
+ 
  # Given N (0..25), return the corresponding alphabetic letter in lower
  # or upper case.  This is ment to be i18n proof.
  
*************** proc test_struct_returns { n } {
*** 330,357 ****
      # Check that the return-value is as expected.  At this stage we're
      # just checking that GDB has returned a value consistent with
      # "return_value_known" set above.
  
      set test "value foo<n> returned; ${tests}"
      gdb_test_multiple "p/c L${n}" "${test}" {
  	-re " = [foo ${n}].*${gdb_prompt} $" {
! 	    if $return_value_known {
! 		pass "${test}"
! 		# This contradicts the above claim that GDB didn't
! 		# know the location of the return-value.
! 	    } else {
! 		fail "${test}"
! 	    }
  	}
! 	-re " = [zed ${n}].*${gdb_prompt} $" {
  	    if $return_value_known {
  		# This contradicts the above claim that GDB knew
! 		# the location of the return-value.
  		fail "${test}"
  	    } else {
! 		# The struct return case.  Since any modification
! 		# would be by reference, and that can't happen, the
! 		# value should be unmodified and hence Z is expected.
! 		# Is this a reasonable assumption?
  		pass "${test}"
  	    }
  	}
--- 353,395 ----
      # Check that the return-value is as expected.  At this stage we're
      # just checking that GDB has returned a value consistent with
      # "return_value_known" set above.
+     #
+     # Note that, when return_value_known is false, we can't make any
+     # assumptions at all about the value L<n>:
+     #
+     # - If the caller passed the address of L<n> directly as fun<n>'s
+     #   return value buffer, then L<n> will be unchanged, because we
+     #   forced fun<n> to return before it could store anything in it.
+     #
+     # - If the caller passed the address of some temporary buffer to
+     #   fun<n>, and then copied the buffer into L<n>, then L<n> will
+     #   have been overwritten with whatever garbage was in the
+     #   uninitialized buffer.
+     #
+     # - However, if the temporary buffer just happened to have the
+     #   "right" value of foo<n> in it, then L<n> will, in fact, have
+     #   the value you'd expect to see if the 'return' had worked!
+     #   This has actually been observed to happen on the Renesas M32C.
+     #
+     # So, really, anything is acceptable unless return_value_known is
+     # true.
  
      set test "value foo<n> returned; ${tests}"
      gdb_test_multiple "p/c L${n}" "${test}" {
  	-re " = [foo ${n}].*${gdb_prompt} $" {
!             # This answer is okay regardless of whether GDB claims to
!             # have set the return value: if it did, then this is what
!             # we expected; and if it didn't, then any answer is okay.
!             pass "${test}"
  	}
! 	-re " = [any $n].*${gdb_prompt} $" {
  	    if $return_value_known {
  		# This contradicts the above claim that GDB knew
! 		# the location of the return value.
  		fail "${test}"
  	    } else {
!                 # We expected L${n} to be set to garbage, so any
!                 # answer is acceptable.
  		pass "${test}"
  	    }
  	}


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