From 989bcc77ab576d7a83cb0194a9fc73ce51939042 Mon Sep 17 00:00:00 2001 From: Daniel Colascione Date: Mon, 4 Jan 2016 14:12:01 -0800 Subject: [PATCH] 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'. --- src/emacs.c | 19 +++++++++++-------- src/keyboard.c | 19 +++++++++++++++++++ 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 -- 2.39.5