This is the mail archive of the gdb-cvs@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]

[binutils-gdb] Fix gdb.base/a2-run.exp race


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=145e3ddb4b1657a1f29eb9f41f2d54d0bf26b6f0

commit 145e3ddb4b1657a1f29eb9f41f2d54d0bf26b6f0
Author: Pedro Alves <palves@redhat.com>
Date:   Fri Oct 9 12:56:26 2015 +0100

    Fix gdb.base/a2-run.exp race
    
    This patch fixes this racy failure, with the native-extended-gdbserver
    board:
    
     (gdb) run
     Starting program: build/gdb/testsuite/outputs/gdb.base/a2-run/a2-run
     Remote debugging from host 127.0.0.1
     Process build/gdb/testsuite/outputs/gdb.base/a2-run/a2-run created; pid = 23832
     Reading /lib64/ld-linux-x86-64.so.2 from remote target...
     warning: File transfers from remote targets can be slow. Use "set sysroot" to access files locally instead.
     Reading /lib64/ld-linux-x86-64.so.2 from remote target...
     Reading /lib64/libm.so.6 from remote target...
     Reading /lib64/libc.so.6 from remote target...
     [Inferior 1 (process 23832) exited with code 01]
     (gdb) FAIL: gdb.base/a2-run.exp: run "a2-run" with no args
     PASS: gdb.base/a2-run.exp: no spurious messages at program exit
     run 5
     Starting program: build/gdb/testsuite/outputs/gdb.base/a2-run/a2-run 5
     Reading /lib64/ld-linux-x86-64.so.2 from remote target...
     usage:  factorial <number>
    
     Child exited with status 1
    
    Note that the output is correct; it's just that inferior output
    appeared after gdb's output, and the test doesn't handle that
    correctly.
    
    This comment isn't really correct, unfortunately:
    
    	# waiting.  If we had already seen the status wrapper exit,
    	# gdb_test_multiple/expect has no spawn ids left, and thus
    	# returns.
    
    That's true of expect in general, but I had missed / forgot that
    gdb_test_multiple internally has extra matches using "-i
    $gdb_spawn_id", so even if the caller clears all the indirect spawn id
    lists, gdb_test_multiple will continue waiting.
    
    So do a conditional exp_continue manually instead.
    
    gdb/testsuite/ChangeLog:
    2015-10-09  Pedro Alves  <palves@redhat.com>
    
    	* gdb.base/a2-run.exp (maybe_exp_continue): New procedure.
    	(top level): Use it in the run with no args test.

Diff:
---
 gdb/testsuite/ChangeLog           |  5 ++++
 gdb/testsuite/gdb.base/a2-run.exp | 54 +++++++++++++++++++++++++--------------
 2 files changed, 40 insertions(+), 19 deletions(-)

diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index 3096936..a48bbee 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2015-10-09  Pedro Alves  <palves@redhat.com>
+
+	* gdb.base/a2-run.exp (maybe_exp_continue): New procedure.
+	(top level): Use it in the run with no args test.
+
 2015-10-08  Iain Buclaw  <ibuclaw@gdcproject.org>
 
 	* gdb.dlang/properties.exp: New file.
diff --git a/gdb/testsuite/gdb.base/a2-run.exp b/gdb/testsuite/gdb.base/a2-run.exp
index dd6af25..8d2302b 100644
--- a/gdb/testsuite/gdb.base/a2-run.exp
+++ b/gdb/testsuite/gdb.base/a2-run.exp
@@ -39,57 +39,73 @@ set saw_spurious_output 0
 
 set test "run \"$testfile\" with no args"
 
+# Indirect spawn id lists.  Used to be able to disable the inferior
+# and gdb's spawn_ids and regexes as soon as we see the expected
+# output.
 set inferior_spawn_list "$inferior_spawn_id"
 set gdb_spawn_list "$gdb_spawn_id"
 
+# Clear either the gdb or the inferior spawn_id list and iff
+# afterwards we still have any spawn id in the indirect lists,
+# continue expecting.
+proc maybe_exp_continue {which} {
+    global inferior_spawn_list gdb_spawn_list
+
+    if {$which == "gdb"} {
+	set gdb_spawn_list ""
+    } elseif {$which == "inferior"} {
+	set inferior_spawn_list ""
+    } else {
+	error "invalid parameter"
+    }
+
+    if {$inferior_spawn_list != "" || $gdb_spawn_list != ""} {
+	exp_continue
+    }
+}
+
+# Note that if $inferior_spawn_id != $gdb_spawn_id the order we pick
+# output from each spawn id is undefined.
 set res [gdb_test_multiple "" $test {
     -i inferior_spawn_list
     -re "usage:  factorial <number>" {
 	set saw_usage 1
-	exp_continue
+	maybe_exp_continue inferior
     }
     -re "EXIT code 1" {
 	set saw_exit_wrapper 1
-	set inferior_spawn_list ""
-	exp_continue
+	maybe_exp_continue inferior
     }
     eof {
 	if {$inferior_spawn_id != $gdb_spawn_id} {
 	    # In this case we may see the server/inferior exit before
 	    # GDB's program exit output.  Remove from spawn list and
 	    # continue waiting.
-	    set inferior_spawn_list ""
-	    exp_continue
+	    maybe_exp_continue inferior
+	} else {
+	    # GDB crash.
+	    fail "$test (eof)"
 	}
-	# GDB crash.
-	fail "$test (eof)"
     }
 
     -i gdb_spawn_list
 
     -re "$inferior_exited_re with code 01.\r\n$gdb_prompt $" {
+	maybe_exp_continue gdb
     }
     -re "$inferior_exited_re with code 01.*$gdb_prompt $" {
 	set saw_spurious_output 1
+	maybe_exp_continue gdb
     }
 
     -re "$inferior_exited_re normally.\r\n$gdb_prompt $" {
 	# This is only considered a pass if we see the exit wrapper
-	# status.  Since if $inferior_spawn_id != $gdb_spawn_id the
-	# order we pick output from each spawn id isn't defined,
-	# remove gdb_spawn_id from the match lists and go back to
-	# waiting.  If we had already seen the status wrapper exit,
-	# gdb_test_multiple/expect has no spawn ids left, and thus
-	# returns.
-	set gdb_spawn_list ""
-	exp_continue
+	# status.
+	maybe_exp_continue gdb
     }
     -re "$inferior_exited_re normally.*$gdb_prompt $" {
 	set saw_spurious_output 1
-
-	# See above.
-	set gdb_spawn_list ""
-	exp_continue
+	maybe_exp_continue gdb
     }
 }]


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