diff options
author | Daniel Colascione <dancol@dancol.org> | 2016-01-04 14:12:01 -0800 |
---|---|---|
committer | Daniel Colascione <dancol@dancol.org> | 2016-01-04 14:12:01 -0800 |
commit | 989bcc77ab576d7a83cb0194a9fc73ce51939042 (patch) | |
tree | 2dbcef6cc44791aa7679978f7b46420c7fe6b454 /src | |
parent | e94b1799d4f4c57266bdbc4801b26fe0121b7c7a (diff) | |
download | emacs-989bcc77ab576d7a83cb0194a9fc73ce51939042.tar.gz emacs-989bcc77ab576d7a83cb0194a9fc73ce51939042.tar.bz2 emacs-989bcc77ab576d7a83cb0194a9fc73ce51939042.zip |
Let users disable unsafe signal handling code
* src/keyboard.c (syms_of_keyboard): New user variables
`attempt-stack-overflow-recovery' and
`attempt-orderly-shutdown-on-fatal-signal'.
* src/sysdep.c (stack_overflow): Check
`attempt-stack-overflow-recovery'.
* src/emacs.c (terminate_due_to_signal): Check
`attempt-orderly-shutdown-on-fatal-signal'.
Diffstat (limited to 'src')
-rw-r--r-- | src/emacs.c | 19 | ||||
-rw-r--r-- | src/keyboard.c | 19 | ||||
-rw-r--r-- | src/sysdep.c | 3 |
3 files changed, 33 insertions, 8 deletions
diff --git a/src/emacs.c b/src/emacs.c index 926aa989e6a..d13413d880b 100644 --- a/src/emacs.c +++ b/src/emacs.c @@ -370,17 +370,20 @@ terminate_due_to_signal (int sig, int backtrace_limit) { signal (sig, SIG_DFL); - /* If fatal error occurs in code below, avoid infinite recursion. */ - if (! fatal_error_in_progress) + if (attempt_orderly_shutdown_on_fatal_signal) { - fatal_error_in_progress = 1; + /* If fatal error occurs in code below, avoid infinite recursion. */ + if (! fatal_error_in_progress) + { + fatal_error_in_progress = 1; - totally_unblock_input (); - if (sig == SIGTERM || sig == SIGHUP || sig == SIGINT) - Fkill_emacs (make_number (sig)); + totally_unblock_input (); + if (sig == SIGTERM || sig == SIGHUP || sig == SIGINT) + Fkill_emacs (make_number (sig)); - shut_down_emacs (sig, Qnil); - emacs_backtrace (backtrace_limit); + shut_down_emacs (sig, Qnil); + emacs_backtrace (backtrace_limit); + } } /* Signal the same code; this time it will really be fatal. diff --git a/src/keyboard.c b/src/keyboard.c index 6fa38aa1328..eb2c7563afd 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -11659,6 +11659,25 @@ Currently, the only supported values for this variable are `sigusr1' and `sigusr2'. */); Vdebug_on_event = intern_c_string ("sigusr2"); + DEFVAR_BOOL ("attempt-stack-overflow-recovery", + attempt_stack_overflow_recovery, + doc: /* If non-nil, attempt to recover from C stack +overflow. This recovery is unsafe and may lead to deadlocks or data +corruption, but it usually works and may preserve modified buffers +that would otherwise be lost. If nil, treat stack overflow like any +other kind of crash. */); + attempt_stack_overflow_recovery = true; + + DEFVAR_BOOL ("attempt-orderly-shutdown-on-fatal-signal", + attempt_orderly_shutdown_on_fatal_signal, + doc: /* If non-nil, attempt to perform an orderly +shutdown when Emacs receives a fatal signal (e.g., a crash). +This cleanup is unsafe and may lead to deadlocks or data corruption, +but it usually works and may preserve modified buffers that would +otherwise be lost. If nil, crash immediately in response to fatal +signals. */); + attempt_orderly_shutdown_on_fatal_signal = true; + /* Create the initial keyboard. Qt means 'unset'. */ initial_kboard = allocate_kboard (Qt); } diff --git a/src/sysdep.c b/src/sysdep.c index 1af323eb8d6..a29155c144a 100644 --- a/src/sysdep.c +++ b/src/sysdep.c @@ -1622,6 +1622,9 @@ static unsigned char sigsegv_stack[SIGSTKSZ]; static bool stack_overflow (siginfo_t *siginfo) { + if (!attempt_stack_overflow_recovery) + return false; + /* In theory, a more-accurate heuristic can be obtained by using GNU/Linux pthread_getattr_np along with POSIX pthread_attr_getstack and pthread_attr_getguardsize to find the location and size of the |