=== modified file 'src/eval.c' --- src/eval.c 2014-02-10 09:48:17 +0000 +++ src/eval.c 2014-03-13 15:02:10 +0000 @@ -33,6 +33,10 @@ #include "xterm.h" #endif +#ifdef HAVE_SYS_RESOURCE_H +#include +#endif + /* Chain of condition and catch handlers currently in effect. */ struct handler *handlerlist; @@ -240,6 +244,32 @@ static struct handler handlerlist_sentinel; +/* C stack overflow protection. */ + +#if defined (HAVE_GETRLIMIT) && defined (RLIMIT_STACK) + +/* Extra stack space to reserve. */ +#define STACK_EXTRA (128 * 1024) + +/* Current C stack slimit. */ +static struct rlimit stack_limit; + +#define STACK_GUARD do { \ + ptrdiff_t stack_size; \ + if ((char *) &stack_size < stack_bottom) \ + stack_size = stack_bottom - (char *) &stack_size; \ + else \ + stack_size = (char *) &stack_size - stack_bottom; \ + if (stack_size + STACK_EXTRA > stack_limit.rlim_cur) \ + error ("Attempt to overflow C stack"); \ + } while (0) + +#else /* !HAVE_GETRLIMIT || !RLIMIT_STACK */ + +#define STACK_GUARD ((void) 0) + +#endif /* HAVE_GETRLIMIT && RLIMIT_STACK */ + void init_eval (void) { @@ -262,6 +292,10 @@ #endif /* This is less than the initial value of num_nonmacro_input_events. */ when_entered_debugger = -1; +#if defined (HAVE_GETRLIMIT) && defined (RLIMIT_STACK) + if (getrlimit (RLIMIT_STACK, &stack_limit)) + emacs_abort (); +#endif /* HAVE_GETRLIMIT && RLIMIT_STACK */ } /* Unwind-protect function used by call_debugger. */ @@ -2060,6 +2094,8 @@ Lisp_Object funcar; struct gcpro gcpro1, gcpro2, gcpro3; + STACK_GUARD; + if (SYMBOLP (form)) { /* Look up its binding in the lexical environment. @@ -2749,6 +2785,8 @@ register Lisp_Object *internal_args; ptrdiff_t i; + STACK_GUARD; + QUIT; if (++lisp_eval_depth > max_lisp_eval_depth)