Fix gdb.threads/process-dies-while-detaching.exp
I noticed [1] a test bug in gdb.threads/process-dies-while-detaching.exp.
Simplified, the test code in question looks somewhat like this:
~~~
# Detach from a process, and ensure that it exits after detaching.
# This relies on inferior I/O.
proc detach_and_expect_exit {test} {
gdb_test_multiple "detach" $test ....
set saw_prompt 0
set saw_inf_exit 0
while { !$saw_prompt && !$saw_inf_exit } {
gdb_test_multiple "" $test {
-re "exited, status=0" {
set saw_inf_exit 1
}
-re "$gdb_prompt " {
set saw_prompt 1
}
}
}
pass $test
}
~~~
The bug is in the while loop's condition. We want to make sure we see
both the inferior output and the prompt, so the loop's test should be:
- while { !$saw_prompt && !$saw_inf_exit } {
+ while { !$saw_prompt || !$saw_inf_exit } {
If we just fix that, the test starts failing though, because it
exposes a couple latent problems:
- When called from test_detach_killed_outside, the parent doesn't
print "exited, status=0", because in that case the child dies with a
signal, and so detach_and_expect_exit times out.
Fix it by making the parent print "signaled, sig=9" in that case,
and have the .exp expect it.
- When testing against --target_board=native-gdbserver, sometimes we'd
get this:
ERROR: Process no longer exists
ERROR: : spawn id exp9 not open
while executing
"expect {
-i exp8 -timeout 220
-i $server_spawn_id
eof {
pass $test
wait -i $server_spawn_id
unset server_spawn_id
}
timeout {
..."
("uplevel" body line 1)
invoked from within
"uplevel $body" NONE : spawn id exp9 not open
The problem is that:
- inferior_spawn_id and server_spawn_id are the same when testing
with gdbserver.
- gdbserver exits after "detach", so we get an eof for
$inferior_spawn_id in the loop in detach_and_expect_exit.
That's the first "ERROR: Process no longer exists".
- and then when we reach test_server_exit, server_spawn_id
is already closed (because server_spawn_id==inferior_spawn_id).
To handle this, make the loop in detach_and_expect_exit use an
indirect spawn id list and remove $inferior_spawn_id from the list
as soon as we got the inferior output we're expecting, so that the
"eof" is left unprocessed until we reach test_server_exit.
[1] I changed GDB in a way that should have made the test fail, but it
didn't.
gdb/testsuite/ChangeLog:
2017-12-03 Pedro Alves <palves@redhat.com>
* gdb.threads/process-dies-while-detaching.c: Include <errno.h>
and <string.h>.
(parent_function): Print distinct messages when waitpid fails, or
the child exits with a signal, or the child exits for an unhandled
reason.
* gdb.threads/process-dies-while-detaching.exp
(detach_and_expect_exit): New 'inf_output_re' parameter and use
it. Wait for both inferior output and GDB's prompt. Use an
indirect spawn id list.
(do_detach): New parameter 'child_exit'. Use it to compute
expected inferior output.
(test_detach, test_detach_watch, test_detach_killed_outside):
Adjust to pass down the expected child exit kind.