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

110 lines
2.3 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>
Avoid gdb.base/fork-running-state.exp lingering processes Currently, the gdb.base/fork-running-state.exp testcase leaves a few processes lingering until a 3 minutes alarm kills them: pedro 28308 1 0 13:55 ? 00:00:00 /home/pedro/gdb/binutils-gdb/build/gdb/testsuite/outputs/gdb.base/fork-running-state/fork-running-state pedro 28340 1 0 13:55 ? 00:00:00 /home/pedro/gdb/binutils-gdb/build/gdb/testsuite/outputs/gdb.base/fork-running-state/fork-running-state pedro 28372 1 0 13:55 ? 00:00:00 /home/pedro/gdb/binutils-gdb/build/gdb/testsuite/outputs/gdb.base/fork-running-state/fork-running-state pedro 28400 1 0 13:55 ? 00:00:00 /home/pedro/gdb/binutils-gdb/build/gdb/testsuite/outputs/gdb.base/fork-running-state/fork-running-state pedro 28431 1 0 13:55 ? 00:00:00 /home/pedro/gdb/binutils-gdb/build/gdb/testsuite/outputs/gdb.base/fork-running-state/fork-running-state pedro 28463 1 0 13:55 ? 00:00:00 /home/pedro/gdb/binutils-gdb/build/gdb/testsuite/outputs/gdb.base/fork-running-state/fork-running-state Those processes used to kill themselves, but that was changed by commit f50d8a2eaea0 ("Fix gdb.base/fork-running-state.exp race"). This commit restores the self-killing, but only in the cases gdb won't try killing the processes, thus avoiding the old race. (The restored code in fork_parent isn't exactly the same as it was. In this version, we're exiting immediately when 'wait' returns success, while in the old version we'd loop again and end up in the perror call. The output from that perror call is not expected by the "kill inferior" tests, and would result in a test FAIL.) gdb/testsuite/ChangeLog: 2018-06-14 Pedro Alves <palves@redhat.com> * gdb.base/fork-running-state.c: Include <errno.h>. (exit_if_relative_exits): New. (fork_child): If 'exit_if_relative_exits' is true, exit if the parent exits. (fork_parent): If 'exit_if_relative_exits' is true, exit if the child exits.
2018-06-14 18:47:03 +02:00
#include <errno.h>
int save_parent;
Avoid gdb.base/fork-running-state.exp lingering processes Currently, the gdb.base/fork-running-state.exp testcase leaves a few processes lingering until a 3 minutes alarm kills them: pedro 28308 1 0 13:55 ? 00:00:00 /home/pedro/gdb/binutils-gdb/build/gdb/testsuite/outputs/gdb.base/fork-running-state/fork-running-state pedro 28340 1 0 13:55 ? 00:00:00 /home/pedro/gdb/binutils-gdb/build/gdb/testsuite/outputs/gdb.base/fork-running-state/fork-running-state pedro 28372 1 0 13:55 ? 00:00:00 /home/pedro/gdb/binutils-gdb/build/gdb/testsuite/outputs/gdb.base/fork-running-state/fork-running-state pedro 28400 1 0 13:55 ? 00:00:00 /home/pedro/gdb/binutils-gdb/build/gdb/testsuite/outputs/gdb.base/fork-running-state/fork-running-state pedro 28431 1 0 13:55 ? 00:00:00 /home/pedro/gdb/binutils-gdb/build/gdb/testsuite/outputs/gdb.base/fork-running-state/fork-running-state pedro 28463 1 0 13:55 ? 00:00:00 /home/pedro/gdb/binutils-gdb/build/gdb/testsuite/outputs/gdb.base/fork-running-state/fork-running-state Those processes used to kill themselves, but that was changed by commit f50d8a2eaea0 ("Fix gdb.base/fork-running-state.exp race"). This commit restores the self-killing, but only in the cases gdb won't try killing the processes, thus avoiding the old race. (The restored code in fork_parent isn't exactly the same as it was. In this version, we're exiting immediately when 'wait' returns success, while in the old version we'd loop again and end up in the perror call. The output from that perror call is not expected by the "kill inferior" tests, and would result in a test FAIL.) gdb/testsuite/ChangeLog: 2018-06-14 Pedro Alves <palves@redhat.com> * gdb.base/fork-running-state.c: Include <errno.h>. (exit_if_relative_exits): New. (fork_child): If 'exit_if_relative_exits' is true, exit if the parent exits. (fork_parent): If 'exit_if_relative_exits' is true, exit if the child exits.
2018-06-14 18:47:03 +02:00
/* Variable set by GDB. If true, then a fork child (or parent) exits
if its parent (or child) exits. Otherwise the process waits
forever until either GDB or the alarm kills it. */
volatile int exit_if_relative_exits = 0;
/* The fork child. Just runs forever. */
static int
fork_child (void)
{
[gdb/testsuite] Fix hang in fork-running-state.c When I run make check: ... $ cd build/gdb $ make check 2>&1 | tee ../CHECKLOG.gdb ... I see after ~30m the summary of the test run printed, but make still hangs. This seems to be due to some sleeping processes: ... $ ps fx | grep fork-run 6475 ? S 0:00 gdb.base/fork-running-state/fork-running-state 6451 ? S 0:00 gdb.base/fork-running-state/fork-running-state 6427 ? S 0:00 gdb.base/fork-running-state/fork-running-state ... Killing the sleeping processes like this: ... kill -9 $(ps -A | grep fork-running-st | awk '{print $1}') ... allows make to finish. If I isolate one debug session from fork-running-state.exp that causes one of these sleeping processes, we get: ... (gdb) set non-stop on (gdb) break main Breakpoint 1 at 0x400665: file src/gdb/testsuite/gdb.base/fork-running-state.c, line 52. (gdb) run Starting program: build/gdb/testsuite/outputs/gdb.base/fork-running-state/ fork-running-state Breakpoint 1, main () at src/gdb/testsuite/gdb.base/fork-running-state.c:52 52 save_parent = getpid (); (gdb) set detach-on-fork on (gdb) set follow-fork parent (gdb) continue & Continuing. [Detaching after fork from child process 18797] (gdb) info threads Id Target Id Frame * 1 process 18793 "fork-running-st" (running) (gdb) set print inferior-events off (gdb) kill inferior 1 ... So, AFAIU, the hanging process is the child process that gdb detaches from. There's an alarm set in main before the fork, but alarms are not preserved in the fork child: ... $ man alarm ... NOTES Alarms created by alarm() are preserved across execve(2) and are not inherited by children created via fork(2). ... So, AFAIU, once the parent is killed, there's no alarm to terminate the child. The patch fixes this by moving the setting of the alarm into the fork_main/fork_child functions, making sure that an alarm will trigger for the child. Tested with make check on x86_64. 2018-06-13 Tom de Vries <tdevries@suse.de> PR testsuite/23269 * gdb.base/fork-running-state.c (main): Move setting of alarm ... (fork_child): ... here, and ... (fork_parent): ... here.
2018-06-10 15:21:31 +02:00
/* Don't run forever. */
alarm (180);
while (1)
Avoid gdb.base/fork-running-state.exp lingering processes Currently, the gdb.base/fork-running-state.exp testcase leaves a few processes lingering until a 3 minutes alarm kills them: pedro 28308 1 0 13:55 ? 00:00:00 /home/pedro/gdb/binutils-gdb/build/gdb/testsuite/outputs/gdb.base/fork-running-state/fork-running-state pedro 28340 1 0 13:55 ? 00:00:00 /home/pedro/gdb/binutils-gdb/build/gdb/testsuite/outputs/gdb.base/fork-running-state/fork-running-state pedro 28372 1 0 13:55 ? 00:00:00 /home/pedro/gdb/binutils-gdb/build/gdb/testsuite/outputs/gdb.base/fork-running-state/fork-running-state pedro 28400 1 0 13:55 ? 00:00:00 /home/pedro/gdb/binutils-gdb/build/gdb/testsuite/outputs/gdb.base/fork-running-state/fork-running-state pedro 28431 1 0 13:55 ? 00:00:00 /home/pedro/gdb/binutils-gdb/build/gdb/testsuite/outputs/gdb.base/fork-running-state/fork-running-state pedro 28463 1 0 13:55 ? 00:00:00 /home/pedro/gdb/binutils-gdb/build/gdb/testsuite/outputs/gdb.base/fork-running-state/fork-running-state Those processes used to kill themselves, but that was changed by commit f50d8a2eaea0 ("Fix gdb.base/fork-running-state.exp race"). This commit restores the self-killing, but only in the cases gdb won't try killing the processes, thus avoiding the old race. (The restored code in fork_parent isn't exactly the same as it was. In this version, we're exiting immediately when 'wait' returns success, while in the old version we'd loop again and end up in the perror call. The output from that perror call is not expected by the "kill inferior" tests, and would result in a test FAIL.) gdb/testsuite/ChangeLog: 2018-06-14 Pedro Alves <palves@redhat.com> * gdb.base/fork-running-state.c: Include <errno.h>. (exit_if_relative_exits): New. (fork_child): If 'exit_if_relative_exits' is true, exit if the parent exits. (fork_parent): If 'exit_if_relative_exits' is true, exit if the child exits.
2018-06-14 18:47:03 +02:00
{
if (exit_if_relative_exits)
{
sleep (1);
/* Exit if GDB kills the parent. */
if (getppid () != save_parent)
break;
if (kill (getppid (), 0) != 0)
break;
}
else
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)
{
[gdb/testsuite] Fix hang in fork-running-state.c When I run make check: ... $ cd build/gdb $ make check 2>&1 | tee ../CHECKLOG.gdb ... I see after ~30m the summary of the test run printed, but make still hangs. This seems to be due to some sleeping processes: ... $ ps fx | grep fork-run 6475 ? S 0:00 gdb.base/fork-running-state/fork-running-state 6451 ? S 0:00 gdb.base/fork-running-state/fork-running-state 6427 ? S 0:00 gdb.base/fork-running-state/fork-running-state ... Killing the sleeping processes like this: ... kill -9 $(ps -A | grep fork-running-st | awk '{print $1}') ... allows make to finish. If I isolate one debug session from fork-running-state.exp that causes one of these sleeping processes, we get: ... (gdb) set non-stop on (gdb) break main Breakpoint 1 at 0x400665: file src/gdb/testsuite/gdb.base/fork-running-state.c, line 52. (gdb) run Starting program: build/gdb/testsuite/outputs/gdb.base/fork-running-state/ fork-running-state Breakpoint 1, main () at src/gdb/testsuite/gdb.base/fork-running-state.c:52 52 save_parent = getpid (); (gdb) set detach-on-fork on (gdb) set follow-fork parent (gdb) continue & Continuing. [Detaching after fork from child process 18797] (gdb) info threads Id Target Id Frame * 1 process 18793 "fork-running-st" (running) (gdb) set print inferior-events off (gdb) kill inferior 1 ... So, AFAIU, the hanging process is the child process that gdb detaches from. There's an alarm set in main before the fork, but alarms are not preserved in the fork child: ... $ man alarm ... NOTES Alarms created by alarm() are preserved across execve(2) and are not inherited by children created via fork(2). ... So, AFAIU, once the parent is killed, there's no alarm to terminate the child. The patch fixes this by moving the setting of the alarm into the fork_main/fork_child functions, making sure that an alarm will trigger for the child. Tested with make check on x86_64. 2018-06-13 Tom de Vries <tdevries@suse.de> PR testsuite/23269 * gdb.base/fork-running-state.c (main): Move setting of alarm ... (fork_child): ... here, and ... (fork_parent): ... here.
2018-06-10 15:21:31 +02:00
/* Don't run forever. */
alarm (180);
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)
Avoid gdb.base/fork-running-state.exp lingering processes Currently, the gdb.base/fork-running-state.exp testcase leaves a few processes lingering until a 3 minutes alarm kills them: pedro 28308 1 0 13:55 ? 00:00:00 /home/pedro/gdb/binutils-gdb/build/gdb/testsuite/outputs/gdb.base/fork-running-state/fork-running-state pedro 28340 1 0 13:55 ? 00:00:00 /home/pedro/gdb/binutils-gdb/build/gdb/testsuite/outputs/gdb.base/fork-running-state/fork-running-state pedro 28372 1 0 13:55 ? 00:00:00 /home/pedro/gdb/binutils-gdb/build/gdb/testsuite/outputs/gdb.base/fork-running-state/fork-running-state pedro 28400 1 0 13:55 ? 00:00:00 /home/pedro/gdb/binutils-gdb/build/gdb/testsuite/outputs/gdb.base/fork-running-state/fork-running-state pedro 28431 1 0 13:55 ? 00:00:00 /home/pedro/gdb/binutils-gdb/build/gdb/testsuite/outputs/gdb.base/fork-running-state/fork-running-state pedro 28463 1 0 13:55 ? 00:00:00 /home/pedro/gdb/binutils-gdb/build/gdb/testsuite/outputs/gdb.base/fork-running-state/fork-running-state Those processes used to kill themselves, but that was changed by commit f50d8a2eaea0 ("Fix gdb.base/fork-running-state.exp race"). This commit restores the self-killing, but only in the cases gdb won't try killing the processes, thus avoiding the old race. (The restored code in fork_parent isn't exactly the same as it was. In this version, we're exiting immediately when 'wait' returns success, while in the old version we'd loop again and end up in the perror call. The output from that perror call is not expected by the "kill inferior" tests, and would result in a test FAIL.) gdb/testsuite/ChangeLog: 2018-06-14 Pedro Alves <palves@redhat.com> * gdb.base/fork-running-state.c: Include <errno.h>. (exit_if_relative_exits): New. (fork_child): If 'exit_if_relative_exits' is true, exit if the parent exits. (fork_parent): If 'exit_if_relative_exits' is true, exit if the child exits.
2018-06-14 18:47:03 +02:00
{
if (exit_if_relative_exits)
{
int res = wait (NULL);
if (res == -1 && errno == EINTR)
continue;
else if (res == -1)
{
perror ("wait");
return 1;
}
else
return 0;
}
else
pause ();
}
return 0;
}
int
main (void)
{
pid_t pid;
save_parent = getpid ();
/* 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;
}
}