]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commit
[gdb/testsuite] Fix hang in fork-running-state.c
authorTom de Vries <tdevries@suse.de>
Sun, 10 Jun 2018 13:21:31 +0000 (15:21 +0200)
committerTom de Vries <tdevries@suse.de>
Wed, 13 Jun 2018 12:15:52 +0000 (14:15 +0200)
commita08ac84b963facb4c4a85c4d5df057d44e2a276d
tree0d8e5c611b7330c104e5738df83d1a2329f8b9b0
parentc75d3d4144fa8b5312bf581451bf800251b7bd71
[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.
gdb/testsuite/gdb.base/fork-running-state.c