GNU Binutils with patches for OS216
修订版 | c6d3683661a7623a306667915abba4d4695616d7 (tree) |
---|---|
时间 | 2020-06-26 00:48:14 |
作者 | Rainer Orth <ro@CeBi...> |
Commiter | Rainer Orth |
Use fork instead of vfork on Solaris
The gdb.mi/mi-exec-run.exp test never completed/timed out on Solaris for
quite some time:
FAIL: gdb.mi/mi-exec-run.exp: inferior-tty=main: mi=main: force-fail=1: run failure detected (timeout)
This is for gdb trying to exec mi-exec-run.nox, a copy of mi-exec-run
with execute permissions removed.
The process tree at this point looks like this:
The parent gdb hangs here:
21294: $obj/gdb/testsuite/../../gdb/gdb -nw
with these process flags
21294: $obj/gdb/testsuite/../../gdb/gdb -nw
data model = _LP64 flags = VFORKP|ORPHAN|MSACCT|MSFORK
sigpend = 0x00004103,0x00000000,0x00000000
sigmask = 0xffbffeff,0xffffffff,0x000000ff
cursig = SIGKILL
why = PR_SUSPENDED
sigmask = 0x000a2002,0x00000000,0x00000000
[...]
while the child sits at
21297: $obj/gdb/testsuite/../../gdb/gdb -nw
with
21297: $obj/gdb/testsuite/../../gdb/gdb -nw
data model = _LP64 flags = MSACCT|MSFORK
exitset = 0x00000000 0x04000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
why = PR_SYSEXIT what = execve
We have a deadlock here: the execve in the child cannot return until the
parent has handled the PR_SYSEXIT while the parent cannot run with a
vfork'ed child as documented in proc(4):
In that situation, the parent cannot be killed even with SIGKILL (as
runtest will attempt once the timeout occurs; the pending signal can be
seen in the pflags output above), so the whole test hangs until one
manually kills the child process.
Fortunately, there's an easy way out: when using fork instead of vfork,
the problem doesn't occur, and this is what the current patch does: it
calls fork_inferior with a dummy pre_trace_fun arg.
Tested on amd64-pc-solaris2.11 and sparcv9-sun-solaris2.11.
* procfs.c (procfs_pre_trace): New function.
(procfs_target::create_inferior): Pass it to fork_inferior.
@@ -1,5 +1,10 @@ | ||
1 | 1 | 2020-06-25 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> |
2 | 2 | |
3 | + * procfs.c (procfs_pre_trace): New function. | |
4 | + (procfs_target::create_inferior): Pass it to fork_inferior. | |
5 | + | |
6 | +2020-06-25 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> | |
7 | + | |
3 | 8 | * configure.tgt <sparc-*-linux*> (gdb_target_obs): Remove |
4 | 9 | sparc-sol2-tdep.o, sol2-tdep.o, sparc64-sol2-tdep.o. |
5 | 10 | <sparc64-*-linux*> (gdb_target_obs): Remove sparc64-sol2-tdep.o, |
@@ -2759,6 +2759,13 @@ procfs_set_exec_trap (void) | ||
2759 | 2759 | /*destroy_procinfo (pi);*/ |
2760 | 2760 | } |
2761 | 2761 | |
2762 | +/* Dummy function to be sure fork_inferior uses fork(2) and not vfork(2). | |
2763 | + This avoids a possible deadlock gdb and its vfork'ed child. */ | |
2764 | +static void | |
2765 | +procfs_pre_trace (void) | |
2766 | +{ | |
2767 | +} | |
2768 | + | |
2762 | 2769 | /* This function is called BEFORE gdb forks the inferior process. Its |
2763 | 2770 | only real responsibility is to set things up for the fork, and tell |
2764 | 2771 | GDB which two functions to call after the fork (one for the parent, |
@@ -2851,7 +2858,7 @@ procfs_target::create_inferior (const char *exec_file, | ||
2851 | 2858 | push_target (this); |
2852 | 2859 | |
2853 | 2860 | pid = fork_inferior (exec_file, allargs, env, procfs_set_exec_trap, |
2854 | - NULL, NULL, shell_file, NULL); | |
2861 | + NULL, procfs_pre_trace, shell_file, NULL); | |
2855 | 2862 | |
2856 | 2863 | /* We have something that executes now. We'll be running through |
2857 | 2864 | the shell at this point (if startup-with-shell is true), but the |