diff options
-rw-r--r-- | src/ChangeLog | 12 | ||||
-rw-r--r-- | src/callproc.c | 4 | ||||
-rw-r--r-- | src/emacs.c | 7 | ||||
-rw-r--r-- | src/process.c | 2 | ||||
-rw-r--r-- | src/process.h | 2 | ||||
-rw-r--r-- | src/sysdep.c | 2 |
6 files changed, 25 insertions, 4 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 202331dac53..b2773ddbf50 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,15 @@ +2013-06-23 Paul Eggert <eggert@cs.ucla.edu> + + Try to avoid malloc SEGVs on Cygwin (Bug#14569). + * callproc.c, process.h (block_child_signal, unblock_child_signal): + Now extern. + * emacs.c (main): Catch SIGCHLD just before initializing gfilenotify. + * process.c (catch_child_signal): Block SIGCHLD while futzing with + the SIGCHLD handler, since the code is not atomic and (due to glib) + signals may be arriving now. + * sysdep.c (init_signals): Do not catch child signals here; + 'main' now does that later, at a safer time. + 2013-06-22 Paul Eggert <eggert@cs.ucla.edu> Clean up SIGCHLD handling a bit (Bug#14569). diff --git a/src/callproc.c b/src/callproc.c index 745d58c45f4..f0aa8222342 100644 --- a/src/callproc.c +++ b/src/callproc.c @@ -84,7 +84,7 @@ static int synch_process_fd; /* Block SIGCHLD. */ -static void +void block_child_signal (void) { sigset_t blocked; @@ -95,7 +95,7 @@ block_child_signal (void) /* Unblock SIGCHLD. */ -static void +void unblock_child_signal (void) { pthread_sigmask (SIG_SETMASK, &empty_mask, 0); diff --git a/src/emacs.c b/src/emacs.c index 13f6d117ebc..c5b32c7c0e7 100644 --- a/src/emacs.c +++ b/src/emacs.c @@ -1257,6 +1257,13 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem tzset (); #endif /* MSDOS */ + /* Do this after initializing the memory allocator, since it uses + glib and glib uses malloc. And do it before anything else that + invokes glib, to avoid potential races among glib subthreads in + Cygwin glib. gfilenotify invokes glib, so this can't be delayed + further. */ + catch_child_signal (); + #ifdef HAVE_GFILENOTIFY globals_of_gfilenotify (); #endif diff --git a/src/process.c b/src/process.c index 3e31dede4c2..6df1bf7eff7 100644 --- a/src/process.c +++ b/src/process.c @@ -7084,11 +7084,13 @@ catch_child_signal (void) #endif emacs_sigaction_init (&action, deliver_child_signal); + block_child_signal (); sigaction (SIGCHLD, &action, &old_action); eassert (! (old_action.sa_flags & SA_SIGINFO)); if (old_action.sa_handler != SIG_DFL && old_action.sa_handler != SIG_IGN && old_action.sa_handler != deliver_child_signal) lib_child_handler = old_action.sa_handler; + unblock_child_signal (); } diff --git a/src/process.h b/src/process.h index 9455df18beb..3f86e5f3945 100644 --- a/src/process.h +++ b/src/process.h @@ -200,6 +200,8 @@ extern Lisp_Object QCflowcontrol, Qhw, Qsw, QCsummary; /* Defined in callproc.c. */ +extern void block_child_signal (void); +extern void unblock_child_signal (void); extern void record_kill_process (struct Lisp_Process *); /* Defined in process.c. */ diff --git a/src/sysdep.c b/src/sysdep.c index c2769865b5d..1d3e646d359 100644 --- a/src/sysdep.c +++ b/src/sysdep.c @@ -1901,8 +1901,6 @@ init_signals (bool dumping) sigaction (SIGFPE, &action, 0); } - catch_child_signal (); - #ifdef SIGUSR1 add_user_signal (SIGUSR1, "sigusr1"); #endif |