From 145e3ddb4b1657a1f29eb9f41f2d54d0bf26b6f0 Mon Sep 17 00:00:00 2001 From: Pedro Alves Date: Fri, 9 Oct 2015 12:56:26 +0100 Subject: [PATCH] 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 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 * gdb.base/a2-run.exp (maybe_exp_continue): New procedure. (top level): Use it in the run with no args test. --- 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 309693629a..a48bbeefba 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2015-10-09 Pedro Alves + + * 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 * 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 dd6af254d5..8d2302b4bd 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 " { 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 } }]