Patchwork robustify guality self-check

login
register
mail settings
Submitter Alexandre Oliva
Date Sept. 23, 2012, 11:11 a.m.
Message ID <orlig1j8ns.fsf@livre.localdomain>
Download mbox | patch
Permalink /patch/186206/
State New
Headers show

Comments

Alexandre Oliva - Sept. 23, 2012, 11:11 a.m.
I found out I wasn't getting any guality tests run.  The old gdb I used
wouldn't recognize line number information at -O0 or something, and this
caused guality.exp to give up.  -O2 -g would have worked, but passing
them to guality_check in either order would cause only the first of the
two to make to the command line, so the test would still fail.  Some
messing with a list and additional quoting to avoid too-early expansion
within the eval took care of that.  But the test still wouldn't work.

Debug info generated for the local variables used by the guality
framework wouldn't be recognized by that old gdb: as a result, the
variables wouldn't be set, and we'd conclude they had incorrect values.
I've now arranged for the variables to be initialized to different
values at each probe point, and if they remain unchanged, we just bump
them up and repeat the probe, with an upper limit of retries large
enough to make room for both probe variables to get values identical to
the initializer, but not for us to loop indefinitely: we quickly realize
when gdb is unable to set the probe variables and error out.

Having taken care of detecting problems, I made the probe variables
global, just like the variable used to detect whether gdb has attached
to the program, and that got things to work at least to some extend with
the older GDB.  However, it looks like we're emitting a lot of debug
info now that the older GDB can't deal with, so...

Having fixed it all, I installed a newer GDB, but I still thing the
patch brings in some useful robustness improvements.  Ok to install?

Regstrapped on x86_64-linux-gnu and i686-linux-gnu.

Patch

Robustify guality tests, fix and improve check_guality

From: Alexandre Oliva <aoliva@redhat.com>

for  gcc/testsuite/ChangeLog

	* gcc.dg/guality/guality.exp (check_guality): Fix compilation
	attempt with -O0 -g, and retry with -O2 -g upon failure.
	* gcc.dg/guality/guality.h (guality_xvalue): New variable.
	(guality_unavailable): Likewise.
	(guality_check): Robustify to cope with failure to set user
	variables, now using the new guality_* variables.
---

 gcc/testsuite/gcc.dg/guality/guality.exp |   19 +++++++++++++
 gcc/testsuite/gcc.dg/guality/guality.h   |   43 +++++++++++++++++++++++-------
 2 files changed, 51 insertions(+), 11 deletions(-)


diff --git a/gcc/testsuite/gcc.dg/guality/guality.exp b/gcc/testsuite/gcc.dg/guality/guality.exp
index 49e2ac5..0c47fa4 100644
--- a/gcc/testsuite/gcc.dg/guality/guality.exp
+++ b/gcc/testsuite/gcc.dg/guality/guality.exp
@@ -9,7 +9,24 @@  if { [istarget *-*-darwin*] } {
 }
 
 proc check_guality {args} {
-    set result [eval check_compile guality_check executable $args "-g -O0"]
+    set options [list "-O0" "-g"]
+    set result [eval check_compile guality_check \
+		    executable $args "\"\$options\""]
+    set lines [lindex $result 0]
+    set output [lindex $result 1]
+    set ret 0
+    if {[string match "" $lines]} {
+      set execout [gcc_load "./$output"]
+      set ret [string match "*1 PASS, 0 FAIL, 0 UNRESOLVED*" $execout]
+    }
+    remote_file build delete $output
+    if {$ret} {
+	return $ret
+    }
+    # Retry with -O2 -g
+    set options [list "-O2" "-g"]
+    set result [eval check_compile guality_check \
+		    executable $args "\"\$options\""]
     set lines [lindex $result 0]
     set output [lindex $result 1]
     set ret 0
diff --git a/gcc/testsuite/gcc.dg/guality/guality.h b/gcc/testsuite/gcc.dg/guality/guality.h
index 8b657f2..9d51893 100644
--- a/gcc/testsuite/gcc.dg/guality/guality.h
+++ b/gcc/testsuite/gcc.dg/guality/guality.h
@@ -194,6 +194,14 @@  int guality_breakpoint_line;
 /* GDB should set this to true once it's connected.  */
 int volatile guality_attached;
 
+/* GDB should set this to the value of the expression we're checking.  */
+gualchk_t volatile guality_xvalue;
+
+/* GDB should set this to a value that tells whether the value was
+   optimized away.  */
+int volatile guality_unavailable;
+
+
 /* This function is the main guality program.  It may actually be
    defined as main, because we #define main to it afterwards.  Because
    of this wrapping, guality_main may not have an empty argument
@@ -283,8 +291,12 @@  guality_check (const char *name, gualchk_t value, int unknown_ok)
     return;
 
   {
-    volatile gualchk_t xvalue = -1;
-    volatile int unavailable = 0;
+    static int test_count;
+    int retry_count = test_count;
+  retry:
+    ++test_count;
+    guality_xvalue = test_count;
+    guality_unavailable = test_count;
     if (name)
       {
 	/* The sequence below cannot distinguish an optimized away
@@ -300,8 +312,8 @@  set $value4 = $value1 + 1\n\
 set $value3 = (%s)++\n\
 set $value4 = --(%s)\n\
 down\n\
-set xvalue = $value1\n\
-set unavailable = $value1 != $value2 ? -1 : $value3 != $value4 ? 1 : 0\n\
+set guality_xvalue = $value1\n\
+set guality_unavailable = $value1 != $value2 ? -1 : $value3 != $value4 ? 1 : 0\n\
 continue\n\
 ", name, name, name, name) <= 0
 	    || fflush (guality_gdb_input))
@@ -322,7 +334,7 @@  continue\n\
 	      ;
 	    if (!timeout && !guality_attached)
 	      {
-		fprintf (stderr, "gdb: took too long to attach\n");
+		fprintf (stderr, "ERROR: gdb: took too long to attach\n");
 		abort ();
 	      }
 	  }
@@ -334,28 +346,39 @@  continue\n\
       }
     /* Do NOT add lines between the __LINE__ above and the line below,
        without also adjusting the added constant to match.  */
-    if (!unavailable || (unavailable > 0 && xvalue))
+    if (guality_xvalue == test_count || guality_unavailable == test_count)
+      {
+	if (test_count - retry_count < 4)
+	  goto retry;
+	  
+	fprintf (stderr, "ERROR: gdb: failed to set interface variables\n");
+	abort ();
+      }
+    if (!guality_unavailable || (guality_unavailable > 0 && guality_xvalue))
       {
-	if (xvalue == value)
+	if (guality_xvalue == value)
 	  result = PASS;
 	else
 	  result = INCORRECT;
       }
     else
       result = INCOMPLETE;
-    asm ("" : : "X" (name), "X" (value), "X" (unknown_ok), "m" (xvalue));
+    asm ("" : : "X" (name), "X" (value), "X" (unknown_ok),
+	 "m" (guality_xvalue));
     switch (result)
       {
       case PASS:
 	fprintf (stderr, "PASS: %s is %lli\n", name, value);
 	break;
       case INCORRECT:
-	fprintf (stderr, "FAIL: %s is %lli, not %lli\n", name, xvalue, value);
+	fprintf (stderr, "FAIL: %s is %lli, not %lli\n", name,
+		 guality_xvalue, value);
 	break;
       case INCOMPLETE:
 	fprintf (stderr, "%s: %s is %s, expected %lli\n",
 		 unknown_ok ? "UNRESOLVED" : "FAIL", name,
-		 unavailable < 0 ? "not computable" : "optimized away", value);
+		 guality_unavailable < 0
+		 ? "not computable" : "optimized away", value);
 	result = unknown_ok ? INCOMPLETE : INCORRECT;
 	break;
       default: