all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* SIGCHLD in vfork child context
@ 2017-05-13  5:41 YAMAMOTO Mitsuharu
  2017-05-15  1:04 ` YAMAMOTO Mitsuharu
  2017-05-16  8:58 ` Paul Eggert
  0 siblings, 2 replies; 13+ messages in thread
From: YAMAMOTO Mitsuharu @ 2017-05-13  5:41 UTC (permalink / raw)
  To: emacs-devel

Recently Emacs on Darwin has changed to use vfork rather than fork for
performance reasons (Bug#26397).  The latest Mac port contains a
similar change, but I received a report telling that this causes
occasional hangs.

It seems that calling waitpid from the SIGCHLD handler results in
ECHILD in the vfork child context, and in this case, Emacs aborts and
then hangs in such a context for some reason on macOS.

src/sysdep.c:
   385	  while (true)
   386	    {
   387	      /* Note: the MS-Windows emulation of waitpid calls maybe_quit
   388		 internally.  */
   389	      if (interruptible)
   390		maybe_quit ();
   391	
   392	      pid = waitpid (child, status, options);
   393	      if (0 <= pid)
   394		break;
   395	
   396	      /* Check that CHILD is a child process that has not been reaped,
   397		 and that STATUS and OPTIONS are valid.  Otherwise abort,
   398		 as continuing after this internal error could cause Emacs to
   399		 become confused and kill innocent-victim processes.  */
   400	      if (errno != EINTR)
   401		emacs_abort ();
   402	    }


I made a patch below to avoid calling the SIGCHLD handler on Darwin,
but I wonder if this can also be meaningful in other platforms.  WDYT?

				     YAMAMOTO Mitsuharu
				mituharu@math.s.chiba-u.ac.jp

diff --git a/src/callproc.c b/src/callproc.c
index 333dbb8cb4..83597bd580 100644
--- a/src/callproc.c
+++ b/src/callproc.c
@@ -634,6 +634,11 @@ call_process (ptrdiff_t nargs, Lisp_Object *args, int filefd,
 
   if (pid == 0)
     {
+#ifdef DARWIN_OS
+      /* Call to waitpid from the SIGCHLD signal handler results in
+	 ECHILD in the vfork child context.  */
+      signal (SIGCHLD, SIG_DFL);
+#endif
       unblock_child_signal (&oldset);
 
 #ifdef DARWIN_OS
@@ -681,6 +686,18 @@ call_process (ptrdiff_t nargs, Lisp_Object *args, int filefd,
 	}
     }
 
+#ifdef DARWIN_OS
+  {
+    struct sigaction action;
+
+    /* Call the SIGCHLD handler in case we have received SIGCHLD in
+       the vfork child context.  The signal mask is restored by
+       unblock_child_signal below.  */
+    sigaction (SIGCHLD, 0, &action);
+    pthread_sigmask (SIG_BLOCK, &action.sa_mask, 0);
+    (*action.sa_handler) (SIGCHLD);
+  }
+#endif
   unblock_child_signal (&oldset);
   unblock_input ();
 
diff --git a/src/process.c b/src/process.c
index c47e1eac52..95867e27db 100644
--- a/src/process.c
+++ b/src/process.c
@@ -1940,6 +1940,11 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
       /* Emacs ignores SIGPIPE, but the child should not.  */
       signal (SIGPIPE, SIG_DFL);
 
+#ifdef DARWIN_OS
+      /* Call to waitpid from the SIGCHLD signal handler results in
+	 ECHILD in the vfork child context.  */
+      signal (SIGCHLD, SIG_DFL);
+#endif
       /* Stop blocking SIGCHLD in the child.  */
       unblock_child_signal (&oldset);
 
@@ -1962,6 +1967,18 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
   if (pid >= 0)
     p->alive = 1;
 
+#ifdef DARWIN_OS
+  {
+    struct sigaction action;
+
+    /* Call the SIGCHLD handler in case we have received SIGCHLD in
+       the vfork child context.  The signal mask is restored by
+       unblock_child_signal below.  */
+    pthread_sigmask (SIG_BLOCK, &action.sa_mask, 0);
+    sigaction (SIGCHLD, 0, &action);
+    (*action.sa_handler) (SIGCHLD);
+  }
+#endif
   /* Stop blocking in the parent.  */
   unblock_child_signal (&oldset);
   unblock_input ();



^ permalink raw reply related	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2017-05-21  9:01 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-05-13  5:41 SIGCHLD in vfork child context YAMAMOTO Mitsuharu
2017-05-15  1:04 ` YAMAMOTO Mitsuharu
2017-05-16  8:58 ` Paul Eggert
2017-05-16  9:19   ` Andreas Schwab
2017-05-16  9:50     ` Paul Eggert
2017-05-16 10:22       ` Andreas Schwab
2017-05-19  7:16         ` Paul Eggert
2017-05-19  3:19   ` YAMAMOTO Mitsuharu
2017-05-19  7:18     ` Paul Eggert
2017-05-20  8:22       ` YAMAMOTO Mitsuharu
2017-05-21  8:49         ` Paul Eggert
2017-05-21  8:53           ` mituharu
2017-05-21  9:01             ` Paul Eggert

Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.