This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC 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]

[testsuite] dg-final { gdb-test { .. } } support


Hi!

For various snippets I've posted in PR41353 the current guality
infrastructure isn't useful, because the guality checks involve a function
call which invalidates any memory and registers in which arguments are
passed, so values can't be expected to be available in many cases.

This patch introduces { dg-final { gdb-test break-on-line varname value } }
notation, which uses gdb to verify that on break-on-line line
varname has value.

Regtested on i686-linux, regtest on x86_64-linux pending.  The example
testcase needs
http://gcc.gnu.org/ml/gcc-patches/2009-09/msg00220.html
http://gcc.gnu.org/ml/gcc-patches/2009-09/msg01017.html
http://gcc.gnu.org/ml/gcc-patches/2009-09/msg01160.html
patches (and a recentish gdb to grok that).

2009-09-17  Jakub Jelinek  <jakub@redhat.com>

	* gcc.dg/guality/guality.exp (gdb-test): New proc for use in dg-final.
	* gcc.dg/guality/pr41353-1.c: New test.

--- gcc/testsuite/gcc.dg/guality/guality.exp.jj	2009-09-04 15:29:55.000000000 +0200
+++ gcc/testsuite/gcc.dg/guality/guality.exp	2009-09-17 14:47:44.000000000 +0200
@@ -15,6 +15,69 @@ proc check_guality {args} {
     return $ret
 }
 
+# Utility for testing variable values using gdb, invoked via dg-final.
+# Call pass if variable has the desired value, otherwise fail.
+#
+# Argument 0 is the line number on which to put a breakpoint
+# Argument 1 is the name of the variable to be checked
+# Argument 2 is the expected value of the variable
+# Argument 3 handles expected failures and the like
+proc gdb-test { args } {
+
+    if { ![isnative] || [is_remote target] } { return }
+
+    if { [llength $args] >= 4 } {
+	switch [dg-process-target [lindex $args 3]] {
+	    "S" { }
+	    "N" { return }
+	    "F" { setup_xfail "*-*-*" }
+	    "P" { }
+	}
+    }
+
+    if [info exists ::env(GUALITY_GDB_NAME)] {
+	set gdb_name "$::env(GUALITY_GDB_NAME)"
+    } else {
+	set gdb_name "gdb"
+    }
+
+    # This assumes that we are three frames down from dg-test, and that
+    # it still stores the filename of the testcase in a local variable "name".
+    # A cleaner solution would require a new DejaGnu release.
+    upvar 2 name testcase
+    upvar 2 prog prog
+
+    set testname "$testcase line [lindex $args 0] [lindex $args 1] == [lindex $args 2]"
+    set output_file "[file rootname [file tail $prog]].exe"
+    set cmd_file "[file rootname [file tail $prog]].gdb"
+
+    set fd [open $cmd_file "w"]
+    puts $fd "break [lindex $args 0]"
+    puts $fd "run"
+    puts $fd "print [lindex $args 1]"
+    puts $fd "print [lindex $args 2]"
+    puts $fd "quit"
+    close $fd
+
+    set fd [open "| $gdb_name -nw -nx -quiet -x $cmd_file ./$output_file 2>/dev/null" r]
+    set text [read $fd]
+    close $fd
+
+    file delete $cmd_file
+
+    if [regexp {[\n\r]\$1 = ([^\n\r]*)[\n\r]+\$2 = ([^\n\r]*)[\n\r]} "$text" dummy first second] {
+	if { $first == $second } {
+	    pass "$testname"
+	} else {
+	    send_log "$first != $second\n"
+	    fail "$testname"
+	}
+    } else {
+	send_log "$text\n"
+	unsupported "$testname"
+    }
+}
+
 dg-init
 
 if {[check_guality "
--- gcc/testsuite/gcc.dg/guality/pr41353-1.c.jj	2009-09-17 12:43:52.000000000 +0200
+++ gcc/testsuite/gcc.dg/guality/pr41353-1.c	2009-09-17 15:04:38.000000000 +0200
@@ -0,0 +1,56 @@
+/* PR debug/41353 */
+/* { dg-do run } */
+/* { dg-options "-g" } */
+
+int vari = 17, varj;
+
+__attribute__((noinline)) int
+f1 (void)
+{
+  /* { dg-final { gdb-test 17 "vari" "17" } } */
+  int vari1 = 2 * vari; /* { dg-final { gdb-test 17 "vari1" "2 * 17" } } */
+  int vari2 = 3 * vari; /* { dg-final { gdb-test 17 "vari2" "3 * 17" } } */
+  int vari3 = 2 * vari; /* { dg-final { gdb-test 17 "vari3" "2 * 17" } } */
+  int vari4 = 3 * vari; /* { dg-final { gdb-test 17 "vari4" "3 * 17" } } */
+  int vari5 = 4 * vari; /* { dg-final { gdb-test 17 "vari5" "4 * 17" } } */
+  int vari6 = 5 * vari; /* { dg-final { gdb-test 17 "vari6" "5 * 17" } } */
+  return varj;
+}
+
+__attribute__((noinline)) int
+f2 (int i, int j)
+{
+  j += i;
+  /* { dg-final { gdb-test 28 "i" "37" } } */
+  /* { dg-final { gdb-test 28 "j" "28 + 37" { xfail *-*-* } } } */
+  int i1 = 2 * i; /* { dg-final { gdb-test 28 "i1" "2 * 37" } } */
+  int i2 = 3 * i; /* { dg-final { gdb-test 28 "i2" "3 * 37" } } */
+  return j;
+}
+
+__attribute__((noinline)) int
+f3 (int i)
+{
+  asm volatile ("" : "+r" (i));
+  /* { dg-final { gdb-test 39 "i" "12" } } */
+  int i1 = 2 * i; /* { dg-final { gdb-test 39 "i1" "2 * 12" } } */
+  int i2 = 2 * i; /* { dg-final { gdb-test 39 "i2" "2 * 12" } } */
+  int i3 = 3 * i; /* { dg-final { gdb-test 39 "i3" "3 * 12" } } */
+  return i;
+}
+
+int (*volatile fnp1) (void) = f1;
+int (*volatile fnp2) (int, int) = f2;
+int (*volatile fnp3) (int) = f3;
+
+int
+main (int argc, char *argv[])
+{
+  asm volatile ("" : : "r" (&fnp1) : "memory");
+  asm volatile ("" : : "r" (&fnp2) : "memory");
+  asm volatile ("" : : "r" (&fnp3) : "memory");
+  fnp1 ();
+  fnp2 (37, 28);
+  fnp3 (12);
+  return 0;
+}

	Jakub


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