Cygwin: make sure exec'ed process exists early in process list
killpg(pgid, 0) (or kill_pgrp(pgid, si_signo=0), in signal.cc) fails (returns -1) even when there is a process in the process group pgid, if the process is in the middle of spawnve(), see https://cygwin.com/pipermail/cygwin/2022-May/251479.html When exec'ing a process the assumption is that the exec'ed process creates its own symlink (in pinfo::thisproc() in pinfo.cc). If the exec'ing process calls NtClose on it's own winpid symlink, but the exec'ed process didn't progress enough into initialization, there's a slim chance that neither the exec'ing process, nor the exec'ed process has a winpid symlink attached. Always create the winpid symlink in spawn.cc, even for exec'ed Cygwin processes. Make sure to dup the handle into the new process, and stop creating the winpid symlink in exec'ed processes. Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
This commit is contained in:
parent
1559f7f458
commit
1b86dd7d8c
|
@ -55,10 +55,11 @@ void
|
|||
pinfo::thisproc (HANDLE h)
|
||||
{
|
||||
procinfo = NULL;
|
||||
bool execed = !!h;
|
||||
|
||||
DWORD flags = PID_IN_USE | PID_ACTIVE;
|
||||
/* Forked process or process started from non-Cygwin parent needs a pid. */
|
||||
if (!h)
|
||||
if (!execed)
|
||||
{
|
||||
cygheap->pid = create_cygwin_pid ();
|
||||
flags |= PID_NEW;
|
||||
|
@ -72,7 +73,8 @@ pinfo::thisproc (HANDLE h)
|
|||
procinfo->dwProcessId = myself_initial.dwProcessId;
|
||||
procinfo->sendsig = myself_initial.sendsig;
|
||||
wcscpy (procinfo->progname, myself_initial.progname);
|
||||
create_winpid_symlink ();
|
||||
if (!execed)
|
||||
create_winpid_symlink ();
|
||||
procinfo->exec_sendsig = NULL;
|
||||
procinfo->exec_dwProcessId = 0;
|
||||
debug_printf ("myself dwProcessId %u", procinfo->dwProcessId);
|
||||
|
|
|
@ -3,3 +3,7 @@ Bug Fixes
|
|||
|
||||
- Fix an issue that command "cmd /c script -c cmd" crashes if it
|
||||
is issued in console of Windows 7.
|
||||
|
||||
- Fix killpg failing because the exec'ing as well as the exec'ed
|
||||
process are not in the pidlist for a brief moment.
|
||||
Addresses: https://cygwin.com/pipermail/cygwin/2022-May/251479.html
|
||||
|
|
|
@ -860,13 +860,14 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv,
|
|||
strace.execing = 1;
|
||||
myself.hProcess = hExeced = pi.hProcess;
|
||||
HANDLE old_winpid_hdl = myself.shared_winpid_handle ();
|
||||
if (!real_path.iscygexec ())
|
||||
{
|
||||
/* If the child process is not a Cygwin process, we have to
|
||||
create a new winpid symlink on behalf of the child process
|
||||
not being able to do this by itself. */
|
||||
myself.create_winpid_symlink ();
|
||||
}
|
||||
/* We have to create a new winpid symlink on behalf of the child
|
||||
process. For Cygwin processes we also have to create a reference
|
||||
in the child. */
|
||||
myself.create_winpid_symlink ();
|
||||
if (real_path.iscygexec ())
|
||||
DuplicateHandle (GetCurrentProcess (),
|
||||
myself.shared_winpid_handle (),
|
||||
pi.hProcess, NULL, 0, 0, DUPLICATE_SAME_ACCESS);
|
||||
NtClose (old_winpid_hdl);
|
||||
real_path.get_wide_win32_path (myself->progname); // FIXME: race?
|
||||
sigproc_printf ("new process name %W", myself->progname);
|
||||
|
|
Loading…
Reference in New Issue