binutils-gdb/gdb/testsuite/gdb.base/fork-running-state.c

72 lines
1.5 KiB
C
Raw Normal View History

/* This testcase is part of GDB, the GNU debugger.
Copyright 2015-2018 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
int save_parent;
/* The fork child. Just runs forever. */
static int
fork_child (void)
{
while (1)
Fix gdb.base/fork-running-state.exp race On my multi-target branch I was occasionaly seeing a FAIL like this: (gdb) PASS: gdb.base/fork-running-state.exp: detach-on-fork=off: follow-fork=parent: non-stop: kill parent [Inferior 2 (process 32672) exited normally] kill inferior 2 warning: Inferior ID 2 is not running. (gdb) FAIL: gdb.base/fork-running-state.exp: detach-on-fork=off: follow-fork=parent: non-stop: kill child (the program exited) ... other similar fails ... Turns out to be a testcase bug/race. A tweak like this increases the changes of hitting the race substancially: --- a/gdb/testsuite/gdb.base/fork-running-state.c +++ b/gdb/testsuite/gdb.base/fork-running-state.c @@ -29,7 +29,7 @@ fork_child (void) { while (1) { - sleep (1); + usleep (100); The testcase has two processes, parent and child fork. The problem is that the child exits itself if it notices the parent is gone, but the testcase .exp does not expect that. I first wrote a patch that handled the different combinations of non-stop/detach-on-fork/follow-fork/schedule-multiple, making the .exp file know when to expect the child to exit itself vs when to kill it explicitly, but the result was that the code to kill the parent and child was getting about as large as the test code that is the actual point of the testcase, above the kills. So I scratched that approach and came up with a simpler patch -- simply make the child not exit itself when the parent exits. The .exp file is going to kill both parent and child explicitly, and, main() already calls alarm() as a safeguard. I don't think we lose anything. gdb/testsuite/ChangeLog: 2018-04-10 Pedro Alves <palves@redhat.com> * gdb.base/fork-running-state.c (fork_child): Don't exit if parent exits. Instead loop running forever. (fork_parent): Run forever too.
2018-04-10 16:00:39 +02:00
pause ();
return 0;
}
Fix gdb.base/fork-running-state.exp race On my multi-target branch I was occasionaly seeing a FAIL like this: (gdb) PASS: gdb.base/fork-running-state.exp: detach-on-fork=off: follow-fork=parent: non-stop: kill parent [Inferior 2 (process 32672) exited normally] kill inferior 2 warning: Inferior ID 2 is not running. (gdb) FAIL: gdb.base/fork-running-state.exp: detach-on-fork=off: follow-fork=parent: non-stop: kill child (the program exited) ... other similar fails ... Turns out to be a testcase bug/race. A tweak like this increases the changes of hitting the race substancially: --- a/gdb/testsuite/gdb.base/fork-running-state.c +++ b/gdb/testsuite/gdb.base/fork-running-state.c @@ -29,7 +29,7 @@ fork_child (void) { while (1) { - sleep (1); + usleep (100); The testcase has two processes, parent and child fork. The problem is that the child exits itself if it notices the parent is gone, but the testcase .exp does not expect that. I first wrote a patch that handled the different combinations of non-stop/detach-on-fork/follow-fork/schedule-multiple, making the .exp file know when to expect the child to exit itself vs when to kill it explicitly, but the result was that the code to kill the parent and child was getting about as large as the test code that is the actual point of the testcase, above the kills. So I scratched that approach and came up with a simpler patch -- simply make the child not exit itself when the parent exits. The .exp file is going to kill both parent and child explicitly, and, main() already calls alarm() as a safeguard. I don't think we lose anything. gdb/testsuite/ChangeLog: 2018-04-10 Pedro Alves <palves@redhat.com> * gdb.base/fork-running-state.c (fork_child): Don't exit if parent exits. Instead loop running forever. (fork_parent): Run forever too.
2018-04-10 16:00:39 +02:00
/* The fork parent. Just runs forever. */
static int
fork_parent (void)
{
Fix gdb.base/fork-running-state.exp race On my multi-target branch I was occasionaly seeing a FAIL like this: (gdb) PASS: gdb.base/fork-running-state.exp: detach-on-fork=off: follow-fork=parent: non-stop: kill parent [Inferior 2 (process 32672) exited normally] kill inferior 2 warning: Inferior ID 2 is not running. (gdb) FAIL: gdb.base/fork-running-state.exp: detach-on-fork=off: follow-fork=parent: non-stop: kill child (the program exited) ... other similar fails ... Turns out to be a testcase bug/race. A tweak like this increases the changes of hitting the race substancially: --- a/gdb/testsuite/gdb.base/fork-running-state.c +++ b/gdb/testsuite/gdb.base/fork-running-state.c @@ -29,7 +29,7 @@ fork_child (void) { while (1) { - sleep (1); + usleep (100); The testcase has two processes, parent and child fork. The problem is that the child exits itself if it notices the parent is gone, but the testcase .exp does not expect that. I first wrote a patch that handled the different combinations of non-stop/detach-on-fork/follow-fork/schedule-multiple, making the .exp file know when to expect the child to exit itself vs when to kill it explicitly, but the result was that the code to kill the parent and child was getting about as large as the test code that is the actual point of the testcase, above the kills. So I scratched that approach and came up with a simpler patch -- simply make the child not exit itself when the parent exits. The .exp file is going to kill both parent and child explicitly, and, main() already calls alarm() as a safeguard. I don't think we lose anything. gdb/testsuite/ChangeLog: 2018-04-10 Pedro Alves <palves@redhat.com> * gdb.base/fork-running-state.c (fork_child): Don't exit if parent exits. Instead loop running forever. (fork_parent): Run forever too.
2018-04-10 16:00:39 +02:00
while (1)
pause ();
return 0;
}
int
main (void)
{
pid_t pid;
save_parent = getpid ();
/* Don't run forever. */
alarm (180);
/* The parent and child should basically run forever without
tripping on any debug event. We want to check that GDB updates
the parent and child running states correctly right after the
fork. */
pid = fork ();
if (pid > 0)
return fork_parent ();
else if (pid == 0)
return fork_child ();
else
{
perror ("fork");
return 1;
}
}