diff options
| author | Paul Eggert | 2012-11-03 11:32:41 -0700 |
|---|---|---|
| committer | Paul Eggert | 2012-11-03 11:32:41 -0700 |
| commit | 0b3d4a4756646cc7e908375a457e36e15712ad00 (patch) | |
| tree | 3aa128c2c41316fc912d10015b428f055ee76bc3 /src/ChangeLog | |
| parent | 0d879dca4648aa15bd3c9ae4ff8b6c39e0c07326 (diff) | |
| download | emacs-0b3d4a4756646cc7e908375a457e36e15712ad00.tar.gz emacs-0b3d4a4756646cc7e908375a457e36e15712ad00.zip | |
Fix a race condition that causes Emacs to mess up glib.
The symptom is a diagnostic "GLib-WARNING **: In call to
g_spawn_sync(), exit status of a child process was requested but
SIGCHLD action was set to SIG_IGN and ECHILD was received by
waitpid(), so exit status can't be returned." The diagnostic
is partly wrong, as the SIGCHLD action is not set to SIG_IGN.
The real bug is a race condition between Emacs and glib: Emacs
does a waitpid (-1, ...) and reaps glib's subprocess by mistake,
so that glib can't find it. Work around the bug by invoking
waitpid only on subprocesses that Emacs itself creates.
* process.c (create_process, record_child_status_change):
Don't use special value -1 in pid field, as the caller now must
know the pid rather than having the callee infer it. The
inference was sometimes incorrect anyway, due to another race.
(create_process): Set new 'alive' member if child is created.
(process_status_retrieved): New function.
(record_child_status_change): Use it.
Accept negative 1st argument, which means to wait for the
processes that Emacs already knows about. Move special-case code
for DOS_NT (which lacks WNOHANG) here, from caller. Keep track of
processes that have already been waited for, by testing and
clearing new 'alive' member.
(CAN_HANDLE_MULTIPLE_CHILDREN): Remove, as record_child_status_change
now does this internally.
(handle_child_signal): Let record_child_status_change do all
the work, since we do not want to reap all exited child processes,
only the child processes that Emacs itself created.
* process.h (Lisp_Process): New boolean member 'alive'.
Fixes: debbugs:8855
Diffstat (limited to 'src/ChangeLog')
| -rw-r--r-- | src/ChangeLog | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 3a88b9c7ce2..2f040accd9a 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,5 +1,34 @@ | |||
| 1 | 2012-11-03 Paul Eggert <eggert@cs.ucla.edu> | 1 | 2012-11-03 Paul Eggert <eggert@cs.ucla.edu> |
| 2 | 2 | ||
| 3 | Fix a race condition that causes Emacs to mess up glib (Bug#8855). | ||
| 4 | The symptom is a diagnostic "GLib-WARNING **: In call to | ||
| 5 | g_spawn_sync(), exit status of a child process was requested but | ||
| 6 | SIGCHLD action was set to SIG_IGN and ECHILD was received by | ||
| 7 | waitpid(), so exit status can't be returned." The diagnostic | ||
| 8 | is partly wrong, as the SIGCHLD action is not set to SIG_IGN. | ||
| 9 | The real bug is a race condition between Emacs and glib: Emacs | ||
| 10 | does a waitpid (-1, ...) and reaps glib's subprocess by mistake, | ||
| 11 | so that glib can't find it. Work around the bug by invoking | ||
| 12 | waitpid only on subprocesses that Emacs itself creates. | ||
| 13 | * process.c (create_process, record_child_status_change): | ||
| 14 | Don't use special value -1 in pid field, as the caller now must | ||
| 15 | know the pid rather than having the callee infer it. The | ||
| 16 | inference was sometimes incorrect anyway, due to another race. | ||
| 17 | (create_process): Set new 'alive' member if child is created. | ||
| 18 | (process_status_retrieved): New function. | ||
| 19 | (record_child_status_change): Use it. | ||
| 20 | Accept negative 1st argument, which means to wait for the | ||
| 21 | processes that Emacs already knows about. Move special-case code | ||
| 22 | for DOS_NT (which lacks WNOHANG) here, from caller. Keep track of | ||
| 23 | processes that have already been waited for, by testing and | ||
| 24 | clearing new 'alive' member. | ||
| 25 | (CAN_HANDLE_MULTIPLE_CHILDREN): Remove, as record_child_status_change | ||
| 26 | now does this internally. | ||
| 27 | (handle_child_signal): Let record_child_status_change do all | ||
| 28 | the work, since we do not want to reap all exited child processes, | ||
| 29 | only the child processes that Emacs itself created. | ||
| 30 | * process.h (Lisp_Process): New boolean member 'alive'. | ||
| 31 | |||
| 3 | Omit duplicate definitions no longer needed with gcc -g3. | 32 | Omit duplicate definitions no longer needed with gcc -g3. |
| 4 | * lisp.h (GCTYPEBITS, GCALIGNMENT, ARRAY_MARK_FLAG, PSEUDOVECTOR_FLAG) | 33 | * lisp.h (GCTYPEBITS, GCALIGNMENT, ARRAY_MARK_FLAG, PSEUDOVECTOR_FLAG) |
| 5 | (VALMASK, MOST_POSITIVE_FIXNUM, MOST_NEGATIVE_FIXNUM): | 34 | (VALMASK, MOST_POSITIVE_FIXNUM, MOST_NEGATIVE_FIXNUM): |