2016-01-25 13:00:20 +01:00
|
|
|
/* This testcase is part of GDB, the GNU debugger.
|
|
|
|
|
2018-01-01 05:43:02 +01:00
|
|
|
Copyright 2015-2018 Free Software Foundation, Inc.
|
2016-01-25 13:00:20 +01:00
|
|
|
|
|
|
|
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>
|
2018-06-14 18:47:03 +02:00
|
|
|
#include <errno.h>
|
2016-01-25 13:00:20 +01:00
|
|
|
|
|
|
|
int save_parent;
|
|
|
|
|
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;
|
|
|
|
|
2016-01-25 13:00:20 +01:00
|
|
|
/* 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);
|
|
|
|
|
2016-01-25 13:00:20 +01:00
|
|
|
while (1)
|
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 ();
|
|
|
|
}
|
2016-01-25 13:00:20 +01:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2018-04-10 16:00:39 +02:00
|
|
|
/* The fork parent. Just runs forever. */
|
2016-01-25 13:00:20 +01:00
|
|
|
|
|
|
|
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);
|
|
|
|
|
2018-04-10 16:00:39 +02:00
|
|
|
while (1)
|
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 ();
|
|
|
|
}
|
2016-01-25 13:00:20 +01:00
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|