summaryrefslogtreecommitdiff
path: root/configure.ac
diff options
context:
space:
mode:
authorDmitry Antipov <dmantipov@yandex.ru>2014-08-26 10:25:59 +0400
committerDmitry Antipov <dmantipov@yandex.ru>2014-08-26 10:25:59 +0400
commitebd31792b292f63f09efa498b5df73bf86107259 (patch)
tree8cd196b0c4c03a3e76e00ed6c0fa010af49d3aea /configure.ac
parent940ac42ae3d5c5c5d80f984278446ab34c0bb26a (diff)
downloademacs-ebd31792b292f63f09efa498b5df73bf86107259.tar.gz
Handle C stack overflow caused by too nested Lisp evaluation.
* configure.ac: Check for sigaltstack and related sigaction support. Unconditionally check for sigsetjmp and siglongjmp. (HAVE_STACK_OVERFLOW_HANDLING): Define if we can support it. * src/lisp.h (toplevel) [HAVE_STACK_OVERFLOW_HANDLING]: Declare siglongjmp point to transfer control from SIGSEGV handler. * src/keyboard.c (return_to_command_loop, recover_top_level_message) [HAVE_STACK_OVERFLOW_HANDLING]: New variables. (regular_top_level_message): New variable. (command_loop) [HAVE_STACK_OVERFLOW_HANDLING]: Handle non-local exit from SIGSEGV handler and adjust message displayed by Vtop_level if appropriate. (syms_of_keyboard): DEFVAR Vtop_level_message and initialize new variables described above. * src/sysdep.c [HAVE_SYS_RESOURCE_H]: Include sys/resource.h as such. (stack_grows_down, sigsegv_stack, handle_sigsegv) [HAVE_STACK_OVERFLOW_HANDLING]: New variables and function. (init_sigsegv): New function. (init_signals): Use it. * lisp/startup.el (normal-top-level): Use top-level-message.
Diffstat (limited to 'configure.ac')
-rw-r--r--configure.ac57
1 files changed, 41 insertions, 16 deletions
diff --git a/configure.ac b/configure.ac
index 967f0195d0f..d6476d2e1c7 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3728,6 +3728,22 @@ if test "$emacs_cv_have_timerfd" = yes; then
[Define to 1 if timerfd functions are supported as in GNU/Linux.])
fi
+# Alternate stack for signal handlers.
+AC_CACHE_CHECK([whether signals can be handled on alternate stack],
+ [emacs_cv_alternate_stack],
+ [AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM([[#include <signal.h>
+ ]],
+ [[stack_t ss;
+ struct sigaction sa;
+ ss.ss_sp = malloc (SIGSTKSZ);
+ ss.ss_size = SIGSTKSZ;
+ sa.sa_flags = SA_SIGINFO | SA_ONSTACK;
+ sigaltstack (&ss, 0);
+ sigaction (SIGSEGV, &sa, 0);]])],
+ [emacs_cv_alternate_stack=yes],
+ [emacs_cv_alternate_stack=no])])
+
# Do we have res_init, for detecting changes in /etc/resolv.conf?
# On Darwin, res_init appears not to be useful: see bug#562 and
# http://lists.gnu.org/archive/html/emacs-devel/2007-11/msg01467.html
@@ -4447,22 +4463,31 @@ AC_CACHE_CHECK([for _setjmp], [emacs_cv_func__setjmp],
[emacs_cv_func__setjmp=no])])
if test $emacs_cv_func__setjmp = yes; then
AC_DEFINE([HAVE__SETJMP], 1, [Define to 1 if _setjmp and _longjmp work.])
-else
- AC_CACHE_CHECK([for sigsetjmp], [emacs_cv_func_sigsetjmp],
- [AC_LINK_IFELSE(
- [AC_LANG_PROGRAM(
- [[#include <setjmp.h>
- ]],
- [[sigjmp_buf j;
- if (! sigsetjmp (j, 1))
- siglongjmp (j, 1);]])],
- [emacs_cv_func_sigsetjmp=yes],
- [emacs_cv_func_sigsetjmp=no])])
- if test $emacs_cv_func_sigsetjmp = yes; then
- AC_DEFINE([HAVE_SIGSETJMP], 1,
- [Define to 1 if sigsetjmp and siglongjmp work.
- The value of this symbol is irrelevant if HAVE__SETJMP is defined.])
- fi
+fi
+
+# We need to preserve signal mask to handle C stack overflows.
+AC_CACHE_CHECK([for sigsetjmp], [emacs_cv_func_sigsetjmp],
+ [AC_LINK_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[#include <setjmp.h>
+ ]],
+ [[sigjmp_buf j;
+ if (! sigsetjmp (j, 1))
+ siglongjmp (j, 1);]])],
+ [emacs_cv_func_sigsetjmp=yes],
+ [emacs_cv_func_sigsetjmp=no])])
+if test $emacs_cv_func_sigsetjmp = yes; then
+ AC_DEFINE([HAVE_SIGSETJMP], 1,
+ [Define to 1 if sigsetjmp and siglongjmp work.])
+fi
+
+# We need all of these features to handle C stack overflows.
+if test "$ac_cv_header_sys_resource_h" = "yes" -a \
+ "$ac_cv_func_getrlimit" = "yes" -a \
+ "$emacs_cv_func_sigsetjmp" = "yes" -a \
+ "$emacs_cv_alternate_stack" = yes; then
+ AC_DEFINE([HAVE_STACK_OVERFLOW_HANDLING], 1,
+ [Define to 1 if C stack overflow can be handled in some cases.])
fi
case $opsys in