aboutsummaryrefslogtreecommitdiffstats
path: root/src/keyboard.c
diff options
context:
space:
mode:
authorDmitry Antipov2014-08-26 10:25:59 +0400
committerDmitry Antipov2014-08-26 10:25:59 +0400
commitebd31792b292f63f09efa498b5df73bf86107259 (patch)
tree8cd196b0c4c03a3e76e00ed6c0fa010af49d3aea /src/keyboard.c
parent940ac42ae3d5c5c5d80f984278446ab34c0bb26a (diff)
downloademacs-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.c33
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;
133static ptrdiff_t before_command_key_count; 133static ptrdiff_t before_command_key_count;
134static ptrdiff_t before_command_echo_length; 134static ptrdiff_t before_command_echo_length;
135 135
136#ifdef HAVE_STACK_OVERFLOW_HANDLING
137
138/* For longjmp to recover from C stack overflow. */
139sigjmp_buf return_to_command_loop;
140
141/* Message displayed by Vtop_level when recovering from C stack overflow. */
142static Lisp_Object recover_top_level_message;
143
144#endif /* HAVE_STACK_OVERFLOW_HANDLING */
145
146/* Message normally displayed by Vtop_level. */
147static 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
138static sys_jmp_buf getcjmp; 151static sys_jmp_buf getcjmp;
@@ -1134,6 +1147,17 @@ static Lisp_Object top_level_1 (Lisp_Object);
1134Lisp_Object 1147Lisp_Object
1135command_loop (void) 1148command_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");