diff options
| author | Dmitry Antipov | 2014-08-26 10:25:59 +0400 |
|---|---|---|
| committer | Dmitry Antipov | 2014-08-26 10:25:59 +0400 |
| commit | ebd31792b292f63f09efa498b5df73bf86107259 (patch) | |
| tree | 8cd196b0c4c03a3e76e00ed6c0fa010af49d3aea /src/keyboard.c | |
| parent | 940ac42ae3d5c5c5d80f984278446ab34c0bb26a (diff) | |
| download | emacs-ebd31792b292f63f09efa498b5df73bf86107259.tar.gz emacs-ebd31792b292f63f09efa498b5df73bf86107259.zip | |
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 'src/keyboard.c')
| -rw-r--r-- | src/keyboard.c | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/src/keyboard.c b/src/keyboard.c index 9b0b19ada2f..ed00b38a7db 100644 --- a/src/keyboard.c +++ b/src/keyboard.c | |||
| @@ -133,6 +133,19 @@ static ptrdiff_t this_single_command_key_start; | |||
| 133 | static ptrdiff_t before_command_key_count; | 133 | static ptrdiff_t before_command_key_count; |
| 134 | static ptrdiff_t before_command_echo_length; | 134 | static ptrdiff_t before_command_echo_length; |
| 135 | 135 | ||
| 136 | #ifdef HAVE_STACK_OVERFLOW_HANDLING | ||
| 137 | |||
| 138 | /* For longjmp to recover from C stack overflow. */ | ||
| 139 | sigjmp_buf return_to_command_loop; | ||
| 140 | |||
| 141 | /* Message displayed by Vtop_level when recovering from C stack overflow. */ | ||
| 142 | static Lisp_Object recover_top_level_message; | ||
| 143 | |||
| 144 | #endif /* HAVE_STACK_OVERFLOW_HANDLING */ | ||
| 145 | |||
| 146 | /* Message normally displayed by Vtop_level. */ | ||
| 147 | static Lisp_Object regular_top_level_message; | ||
| 148 | |||
| 136 | /* For longjmp to where kbd input is being done. */ | 149 | /* For longjmp to where kbd input is being done. */ |
| 137 | 150 | ||
| 138 | static sys_jmp_buf getcjmp; | 151 | static sys_jmp_buf getcjmp; |
| @@ -1134,6 +1147,17 @@ static Lisp_Object top_level_1 (Lisp_Object); | |||
| 1134 | Lisp_Object | 1147 | Lisp_Object |
| 1135 | command_loop (void) | 1148 | command_loop (void) |
| 1136 | { | 1149 | { |
| 1150 | #ifdef HAVE_STACK_OVERFLOW_HANDLING | ||
| 1151 | /* At least on GNU/Linux, saving signal mask is important here. */ | ||
| 1152 | if (sigsetjmp (return_to_command_loop, 1) != 0) | ||
| 1153 | { | ||
| 1154 | /* Comes here from handle_sigsegv, see sysdep.c. */ | ||
| 1155 | init_eval (); | ||
| 1156 | Vtop_level_message = recover_top_level_message; | ||
| 1157 | } | ||
| 1158 | else | ||
| 1159 | Vtop_level_message = regular_top_level_message; | ||
| 1160 | #endif /* HAVE_STACK_OVERFLOW_HANDLING */ | ||
| 1137 | if (command_loop_level > 0 || minibuf_level > 0) | 1161 | if (command_loop_level > 0 || minibuf_level > 0) |
| 1138 | { | 1162 | { |
| 1139 | Lisp_Object val; | 1163 | Lisp_Object val; |
| @@ -11000,6 +11024,15 @@ syms_of_keyboard (void) | |||
| 11000 | Vlispy_mouse_stem = build_pure_c_string ("mouse"); | 11024 | Vlispy_mouse_stem = build_pure_c_string ("mouse"); |
| 11001 | staticpro (&Vlispy_mouse_stem); | 11025 | staticpro (&Vlispy_mouse_stem); |
| 11002 | 11026 | ||
| 11027 | regular_top_level_message = build_pure_c_string ("Back to top level"); | ||
| 11028 | #ifdef HAVE_STACK_OVERFLOW_HANDLING | ||
| 11029 | recover_top_level_message | ||
| 11030 | = build_pure_c_string ("Re-entering top level after C stack overflow"); | ||
| 11031 | #endif | ||
| 11032 | DEFVAR_LISP ("top-level-message", Vtop_level_message, | ||
| 11033 | doc: /* Message displayed by `normal-top-level'. */); | ||
| 11034 | Vtop_level_message = regular_top_level_message; | ||
| 11035 | |||
| 11003 | /* Tool-bars. */ | 11036 | /* Tool-bars. */ |
| 11004 | DEFSYM (QCimage, ":image"); | 11037 | DEFSYM (QCimage, ":image"); |
| 11005 | DEFSYM (Qhelp_echo, "help-echo"); | 11038 | DEFSYM (Qhelp_echo, "help-echo"); |