]> sourceware.org Git - newlib-cygwin.git/commitdiff
Cygwin: make sure exec'ed process exists early in process list
authorCorinna Vinschen <corinna@vinschen.de>
Thu, 19 May 2022 08:46:33 +0000 (10:46 +0200)
committerCorinna Vinschen <corinna@vinschen.de>
Thu, 19 May 2022 08:46:41 +0000 (10:46 +0200)
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>
winsup/cygwin/pinfo.cc
winsup/cygwin/release/3.3.6
winsup/cygwin/spawn.cc

index 4a8daefd924ec0fd962e692e7922f1495c17457d..f501c470f34cd83c470f2ffafa4b7207db16beb5 100644 (file)
@@ -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);
index 6d1f0bc8bfff46754933271901fa3453791103e0..6d722433f6ab8b7aec14995cf0e72dbf101085ba 100644 (file)
@@ -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
index 98b588698c5c86ef64c1d3893e26fea2a5d3a3c6..905d949fc5c447a9ac0642a29128730e6fc22c7f 100644 (file)
@@ -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);
This page took 0.033889 seconds and 5 git commands to generate.