diff options
| author | Daniel Colascione | 2016-01-04 14:12:01 -0800 |
|---|---|---|
| committer | Daniel Colascione | 2016-01-04 14:12:01 -0800 |
| commit | 989bcc77ab576d7a83cb0194a9fc73ce51939042 (patch) | |
| tree | 2dbcef6cc44791aa7679978f7b46420c7fe6b454 /src | |
| parent | e94b1799d4f4c57266bdbc4801b26fe0121b7c7a (diff) | |
| download | emacs-989bcc77ab576d7a83cb0194a9fc73ce51939042.tar.gz 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) | |||
| 370 | { | 370 | { |
| 371 | signal (sig, SIG_DFL); | 371 | signal (sig, SIG_DFL); |
| 372 | 372 | ||
| 373 | /* If fatal error occurs in code below, avoid infinite recursion. */ | 373 | if (attempt_orderly_shutdown_on_fatal_signal) |
| 374 | if (! fatal_error_in_progress) | ||
| 375 | { | 374 | { |
| 376 | fatal_error_in_progress = 1; | 375 | /* If fatal error occurs in code below, avoid infinite recursion. */ |
| 376 | if (! fatal_error_in_progress) | ||
| 377 | { | ||
| 378 | fatal_error_in_progress = 1; | ||
| 377 | 379 | ||
| 378 | totally_unblock_input (); | 380 | totally_unblock_input (); |
| 379 | if (sig == SIGTERM || sig == SIGHUP || sig == SIGINT) | 381 | if (sig == SIGTERM || sig == SIGHUP || sig == SIGINT) |
| 380 | Fkill_emacs (make_number (sig)); | 382 | Fkill_emacs (make_number (sig)); |
| 381 | 383 | ||
| 382 | shut_down_emacs (sig, Qnil); | 384 | shut_down_emacs (sig, Qnil); |
| 383 | emacs_backtrace (backtrace_limit); | 385 | emacs_backtrace (backtrace_limit); |
| 386 | } | ||
| 384 | } | 387 | } |
| 385 | 388 | ||
| 386 | /* Signal the same code; this time it will really be fatal. | 389 | /* 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 | |||
| 11659 | variable are `sigusr1' and `sigusr2'. */); | 11659 | variable are `sigusr1' and `sigusr2'. */); |
| 11660 | Vdebug_on_event = intern_c_string ("sigusr2"); | 11660 | Vdebug_on_event = intern_c_string ("sigusr2"); |
| 11661 | 11661 | ||
| 11662 | DEFVAR_BOOL ("attempt-stack-overflow-recovery", | ||
| 11663 | attempt_stack_overflow_recovery, | ||
| 11664 | doc: /* If non-nil, attempt to recover from C stack | ||
| 11665 | overflow. This recovery is unsafe and may lead to deadlocks or data | ||
| 11666 | corruption, but it usually works and may preserve modified buffers | ||
| 11667 | that would otherwise be lost. If nil, treat stack overflow like any | ||
| 11668 | other kind of crash. */); | ||
| 11669 | attempt_stack_overflow_recovery = true; | ||
| 11670 | |||
| 11671 | DEFVAR_BOOL ("attempt-orderly-shutdown-on-fatal-signal", | ||
| 11672 | attempt_orderly_shutdown_on_fatal_signal, | ||
| 11673 | doc: /* If non-nil, attempt to perform an orderly | ||
| 11674 | shutdown when Emacs receives a fatal signal (e.g., a crash). | ||
| 11675 | This cleanup is unsafe and may lead to deadlocks or data corruption, | ||
| 11676 | but it usually works and may preserve modified buffers that would | ||
| 11677 | otherwise be lost. If nil, crash immediately in response to fatal | ||
| 11678 | signals. */); | ||
| 11679 | attempt_orderly_shutdown_on_fatal_signal = true; | ||
| 11680 | |||
| 11662 | /* Create the initial keyboard. Qt means 'unset'. */ | 11681 | /* Create the initial keyboard. Qt means 'unset'. */ |
| 11663 | initial_kboard = allocate_kboard (Qt); | 11682 | initial_kboard = allocate_kboard (Qt); |
| 11664 | } | 11683 | } |
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]; | |||
| 1622 | static bool | 1622 | static bool |
| 1623 | stack_overflow (siginfo_t *siginfo) | 1623 | stack_overflow (siginfo_t *siginfo) |
| 1624 | { | 1624 | { |
| 1625 | if (!attempt_stack_overflow_recovery) | ||
| 1626 | return false; | ||
| 1627 | |||
| 1625 | /* In theory, a more-accurate heuristic can be obtained by using | 1628 | /* In theory, a more-accurate heuristic can be obtained by using |
| 1626 | GNU/Linux pthread_getattr_np along with POSIX pthread_attr_getstack | 1629 | GNU/Linux pthread_getattr_np along with POSIX pthread_attr_getstack |
| 1627 | and pthread_attr_getguardsize to find the location and size of the | 1630 | and pthread_attr_getguardsize to find the location and size of the |