aboutsummaryrefslogtreecommitdiffstats
path: root/src/eval.c
diff options
context:
space:
mode:
authorPaul Eggert2012-09-23 01:44:20 -0700
committerPaul Eggert2012-09-23 01:44:20 -0700
commit4d7e6e51dd4acecff466a28d958c50f34fc130b8 (patch)
tree5e340d48fb69f9a40a4304cc94db2006caefe51f /src/eval.c
parent8f4635e97e1587c4026ec83fc1bd9f8954775915 (diff)
downloademacs-4d7e6e51dd4acecff466a28d958c50f34fc130b8.tar.gz
emacs-4d7e6e51dd4acecff466a28d958c50f34fc130b8.zip
Simplify and avoid signal-handling races.
* nt/inc/ms-w32.h (emacs_raise): New macro. * src/alloc.c (die): * src/sysdep.c (emacs_abort) [HAVE_NTGUI]: Avoid recursive loop if there's a fatal error in the function itself. * src/atimer.c (pending_atimers): * src/blockinput.h: Don't include "atimer.h"; no longer needed. (interrupt_input_pending): Remove. All uses removed. pending_signals now counts both atimers and ordinary interrupts. This is less racy than having three separate pending-signal flags. (block_input, unblock_input, totally_unblock_input, unblock_input_to) (input_blocked_p): Rename from their upper-case counterparts BLOCK_INPUT, UNBLOCK_INPUT, TOTALLY_UNBLOCK_INPUT, UNBLOCK_INPUT_TO, INPUT_BLOCKED_P, and turn into functions. All uses changed. This makes it easier to access volatile variables more accurately. (BLOCK_INPUT_RESIGNAL): Remove. All uses replaced by unblock_input (). (input_blocked_p): Prefer this to 'interrupt_input_blocked', as that's more reliable if the code is buggy and sets interrupt_input_blocked to a negative value. All uses changed. * src/atimer.c (deliver_alarm_signal): Remove. No need to deliver this to the parent; any thread can handle this signal now. All uses replaced by underlying handler. * src/atimer.c (turn_on_atimers): * src/dispnew.c (handle_window_change_signal): * src/emacs.c (handle_danger_signal): * src/keyboard.c (kbd_buffer_get_event): Don't reestablish signal handler; not needed with sigaction. * src/blockinput.h (UNBLOCK_INPUT_TO, TOTALLY_UNBLOCK_INPUT) (UNBLOCK_INPUT_TO): Rework to avoid unnecessary accesses to volatile variables. (UNBLOCK_INPUT_TO): Now a function. (totally_unblock_input, unblock_input): New decls. * src/data.c (handle_arith_signal, deliver_arith_signal): Move to sysdep.c (init_data): Remove. Necessary stuff now done in init_signal. * src/emacs.c, src/xdisp.c: Include "atimer.h", since we invoke atimer functions. * src/emacs.c (handle_fatal_signal, deliver_fatal_signal): Move to sysdep.c. (fatal_error_code): Remove; no longer needed. (terminate_due_to_signal): Rename from fatal_error_backtrace, since it doesn't always backtrace. All uses changed. No need to reset signal to default, since sigaction and/or die does that for us now. Use emacs_raise (FOO), not kill (getpid (), FOO). (main): Check more-accurately whether we're dumping. Move fatal-error setup to sysdep.c * src/floatfns.c: Do not include "syssignal.h"; no longer needed. * src/gtkutil.c (xg_get_file_name, xg_get_font): Remove no-longer-needed signal-mask manipulation. * src/keyboard.c, src/process.c (POLL_FOR_INPUT): Don't depend on USE_ASYNC_EVENTS, a symbol that is never defined. * src/keyboard.c (read_avail_input): Remove. All uses replaced by gobble_input. (Ftop_level): Use TOTALLY_UNBLOCK_INPUT rather than open code. (kbd_buffer_store_event_hold, gobble_input): (record_asynch_buffer_change) [USABLE_SIGIO]: (store_user_signal_events): No need to mess with signal mask. (gobble_input): If blocking input and there are terminals, simply set pending_signals to 1 and return. All hooks changed to not worry about whether input is blocked. (process_pending_signals): Clear pending_signals before processing them, in case a signal comes in while we're processing. By convention callers now test pending_signals before calling us. (UNBLOCK_INPUT_TO, unblock_input, totally_unblock_input): New functions, to support changes to blockinput.h. (handle_input_available_signal): Now extern. (reinvoke_input_signal): Remove. All uses replaced by handle_async_input. (quit_count): Now volatile, since a signal handler uses it. (handle_interrupt): Now takes bool IN_SIGNAL_HANDLER as arg. All callers changed. Block SIGINT only if not already blocked. Clear sigmask reliably, even if Fsignal returns, which it can. Omit unnecessary accesses to volatile var. (quit_throw_to_read_char): No need to restore sigmask. * src/keyboard.c (gobble_input, handle_user_signal): * src/process.c (wait_reading_process_output): Call signal-handling code rather than killing ourselves. * src/lisp.h: Include <float.h>, for... (IEEE_FLOATING_POINT): New macro, moved here to avoid duplication. (pending_signals): Now volatile. (syms_of_data): Now const if IEEE floating point. (handle_input_available_signal) [USABLE_SIGIO]: (terminate_due_to_signal, record_child_status_change): New decls. * src/process.c (create_process): Avoid disaster if memory is exhausted while we're processing a vfork, by tightening the critical section around the vfork. (send_process_frame, process_sent_to, handle_pipe_signal) (deliver_pipe_signal): Remove. No longer needed, as Emacs now ignores SIGPIPE. (send_process): No need for setjmp/longjmp any more, since the SIGPIPE stuff is now gone. Instead, report an error if errno is EPIPE. (record_child_status_change): Now extern. PID and W are now args. Return void, not bool. All callers changed. * src/sysdep.c (wait_debugging) [(BSD_SYSTEM || HPUX) && !defined (__GNU__)]: Remove. All uses removed. This bug should be fixed now in a different way. (wait_for_termination_1): Use waitpid rather than sigsuspend, and record the child status change directly. This avoids the need to futz with the signal mask. (process_fatal_action): Move here from emacs.c. (emacs_sigaction_flags): New function, containing much of what used to be in emacs_sigaction_init. (emacs_sigaction_init): Use it. Block nonfatal system signals that are caught by emacs, to make races less likely. (deliver_process_signal): Rename from handle_on_main_thread. All uses changed. (BACKTRACE_LIMIT_MAX): Now at top level. (thread_backtrace_buffer, threadback_backtrace_pointers): New static vars. (deliver_thread_signal, deliver_fatal_thread_signal): New functions, for more-accurate delivery of thread-specific signals. (handle_fatal_signal, deliver_fatal_signal): Move here from emacs.c. (deliver_arith_signal): Handle in this thread, not in the main thread, since it's triggered by this thread. (maybe_fatal_sig): New function. (init_signals): New arg DUMPING so that we can be more accurate about whether we're dumping. Caller changed. Treat thread-specific signals differently from process-general signals. Block all signals while handling fatal error; that's safer. xsignal from SIGFPE only on non-IEEE hosts, treating it as fatal on IEEE hosts. When batch, ignore SIGHUP, SIGINT, SIGTERM if they were already ignored. Ignore SIGPIPE unless batch. (emacs_backtrace): Output backtrace for the appropriate thread, which is not necessarily the main thread. * src/syssignal.h: Include <stdbool.h>. (emacs_raise): New macro. * src/xterm.c (x_connection_signal): Remove; no longer needed now that we use sigaction. (x_connection_closed): No need to mess with sigmask now. (x_initialize): No need to reset SIGPIPE handler here, since init_signals does this for us now. Fixes: debbugs:12471
Diffstat (limited to 'src/eval.c')
-rw-r--r--src/eval.c18
1 files changed, 4 insertions, 14 deletions
diff --git a/src/eval.c b/src/eval.c
index e47478bb1f1..25a41486279 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -1076,7 +1076,7 @@ internal_catch (Lisp_Object tag, Lisp_Object (*func) (Lisp_Object), Lisp_Object
1076/* Unwind the specbind, catch, and handler stacks back to CATCH, and 1076/* Unwind the specbind, catch, and handler stacks back to CATCH, and
1077 jump to that CATCH, returning VALUE as the value of that catch. 1077 jump to that CATCH, returning VALUE as the value of that catch.
1078 1078
1079 This is the guts Fthrow and Fsignal; they differ only in the way 1079 This is the guts of Fthrow and Fsignal; they differ only in the way
1080 they choose the catch tag to throw to. A catch tag for a 1080 they choose the catch tag to throw to. A catch tag for a
1081 condition-case form has a TAG of Qnil. 1081 condition-case form has a TAG of Qnil.
1082 1082
@@ -1085,7 +1085,7 @@ internal_catch (Lisp_Object tag, Lisp_Object (*func) (Lisp_Object), Lisp_Object
1085 the handler stack as we go, so that the proper handlers are in 1085 the handler stack as we go, so that the proper handlers are in
1086 effect for each unwind-protect clause we run. At the end, restore 1086 effect for each unwind-protect clause we run. At the end, restore
1087 some static info saved in CATCH, and longjmp to the location 1087 some static info saved in CATCH, and longjmp to the location
1088 specified in the 1088 specified there.
1089 1089
1090 This is used for correct unwinding in Fthrow and Fsignal. */ 1090 This is used for correct unwinding in Fthrow and Fsignal. */
1091 1091
@@ -1099,7 +1099,7 @@ unwind_to_catch (struct catchtag *catch, Lisp_Object value)
1099 1099
1100 /* Restore certain special C variables. */ 1100 /* Restore certain special C variables. */
1101 set_poll_suppress_count (catch->poll_suppress_count); 1101 set_poll_suppress_count (catch->poll_suppress_count);
1102 UNBLOCK_INPUT_TO (catch->interrupt_input_blocked); 1102 unblock_input_to (catch->interrupt_input_blocked);
1103 immediate_quit = 0; 1103 immediate_quit = 0;
1104 1104
1105 do 1105 do
@@ -1114,16 +1114,6 @@ unwind_to_catch (struct catchtag *catch, Lisp_Object value)
1114 } 1114 }
1115 while (! last_time); 1115 while (! last_time);
1116 1116
1117#if HAVE_X_WINDOWS
1118 /* If x_catch_errors was done, turn it off now.
1119 (First we give unbind_to a chance to do that.) */
1120#if 0 /* This would disable x_catch_errors after x_connection_closed.
1121 The catch must remain in effect during that delicate
1122 state. --lorentey */
1123 x_fully_uncatch_errors ();
1124#endif
1125#endif
1126
1127 byte_stack_list = catch->byte_stack; 1117 byte_stack_list = catch->byte_stack;
1128 gcprolist = catch->gcpro; 1118 gcprolist = catch->gcpro;
1129#ifdef DEBUG_GCPRO 1119#ifdef DEBUG_GCPRO
@@ -1713,7 +1703,7 @@ maybe_call_debugger (Lisp_Object conditions, Lisp_Object sig, Lisp_Object data)
1713 if ( 1703 if (
1714 /* Don't try to run the debugger with interrupts blocked. 1704 /* Don't try to run the debugger with interrupts blocked.
1715 The editing loop would return anyway. */ 1705 The editing loop would return anyway. */
1716 ! INPUT_BLOCKED_P 1706 ! input_blocked_p ()
1717 && NILP (Vinhibit_debugger) 1707 && NILP (Vinhibit_debugger)
1718 /* Does user want to enter debugger for this kind of error? */ 1708 /* Does user want to enter debugger for this kind of error? */
1719 && (EQ (sig, Qquit) 1709 && (EQ (sig, Qquit)