The default value of this variable is 1600. If you set it to a value
less than 100, Lisp will reset it to 100 if the given value is
-reached. Entry to the Lisp debugger increases the value, if there is
-little room left, to make sure the debugger itself has room to
-execute.
+reached.
@end defopt
+@defopt lisp-eval-depth-reserve
+In order to be able to debug infinite recursion errors, when invoking the
+Lisp debugger, Emacs increases temporarily the value of
+@code{max-lisp-eval-depth}, if there is little room left, to make sure
+the debugger itself has room to execute. The same happens when
+running the handler of a @code{handler-bind}. @xref{Handling Errors}.
+
+The variable @code{lisp-eval-depth-reserve} bounds the extra depth
+that Emacs can add to @code{max-lisp-eval-depth} for those
+exceptional circumstances.
+
+The default value of this variable is 200.
+@end defopt
+
+
@defvar values
The value of this variable is a list of the values returned by all the
expressions that were read, evaluated, and printed from buffers
init_eval_once (void)
{
/* Don't forget to update docs (lispref node "Eval"). */
- max_lisp_eval_depth = 1600;
Vrun_hooks = Qnil;
pdumper_do_now_and_after_load (init_eval_once_for_pdumper);
}
redisplay_deep_handler = NULL;
}
-/* Ensure that *M is at least A + B if possible, or is its maximum
- value otherwise. */
-
static void
-max_ensure_room (intmax_t *m, intmax_t a, intmax_t b)
+restore_stack_limits (Lisp_Object data)
{
- intmax_t sum = ckd_add (&sum, a, b) ? INTMAX_MAX : sum;
- *m = max (*m, sum);
+ intmax_t old_depth;
+ integer_to_intmax (data, &old_depth);
+ lisp_eval_depth_reserve += max_lisp_eval_depth - old_depth;
+ max_lisp_eval_depth = old_depth;
}
-/* Unwind-protect function used by call_debugger. */
+/* Try and ensure that we have at least B dpeth available. */
static void
-restore_stack_limits (Lisp_Object data)
+max_ensure_room (intmax_t b)
{
- integer_to_intmax (data, &max_lisp_eval_depth);
+ intmax_t sum = ckd_add (&sum, lisp_eval_depth, b) ? INTMAX_MAX : sum;
+ intmax_t diff = min (sum - max_lisp_eval_depth, lisp_eval_depth_reserve);
+ if (diff <= 0)
+ return;
+ intmax_t old_depth = max_lisp_eval_depth;
+ max_lisp_eval_depth += diff;
+ lisp_eval_depth_reserve -= diff;
+ /* Restore limits after leaving the debugger. */
+ record_unwind_protect (restore_stack_limits, make_int (old_depth));
}
/* Call the Lisp debugger, giving it argument ARG. */
bool debug_while_redisplaying;
specpdl_ref count = SPECPDL_INDEX ();
Lisp_Object val;
- intmax_t old_depth = max_lisp_eval_depth;
/* The previous value of 40 is too small now that the debugger
prints using cl-prin1 instead of prin1. Printing lists nested 8
deep (which is the value of print-level used in the debugger)
currently requires 77 additional frames. See bug#31919. */
- max_ensure_room (&max_lisp_eval_depth, lisp_eval_depth, 100);
-
- /* Restore limits after leaving the debugger. */
- record_unwind_protect (restore_stack_limits, make_int (old_depth));
+ max_ensure_room (100);
#ifdef HAVE_WINDOW_SYSTEM
if (display_hourglass_p)
/* This hook is used by edebug. */
if (! NILP (Vsignal_hook_function)
- && ! NILP (error_symbol)
- /* Don't try to call a lisp function if we've already overflowed
- the specpdl stack. */
- && specpdl_ptr < specpdl_end)
+ && ! NILP (error_symbol))
{
- /* Edebug takes care of restoring these variables when it exits. */
- max_ensure_room (&max_lisp_eval_depth, lisp_eval_depth, 20);
-
+ specpdl_ref count = SPECPDL_INDEX ();
+ max_ensure_room (20);
/* FIXME: 'handler-bind' makes `signal-hook-function' obsolete? */
call2 (Vsignal_hook_function, error_symbol, data);
+ unbind_to (count, Qnil);
}
conditions = Fget (real_error_symbol, Qerror_conditions);
Lisp_Object error_data
= (NILP (error_symbol)
? data : Fcons (error_symbol, data));
+ specpdl_ref count = SPECPDL_INDEX ();
+ max_ensure_room (20);
push_handler (make_fixnum (skip + h->bytecode_dest),
SKIP_CONDITIONS);
call1 (h->val, error_data);
+ unbind_to (count, Qnil);
pop_handler ();
}
continue;
&& NILP (Vinhibit_debugger)
&& !NILP (Ffboundp (Qdebug_early)))
{
- max_ensure_room (&max_lisp_eval_depth, lisp_eval_depth, 100);
specpdl_ref count = SPECPDL_INDEX ();
+ max_ensure_room (100);
AUTO_STRING (redisplay_trace, "*Redisplay-trace*");
Lisp_Object redisplay_trace_buffer;
AUTO_STRING (gap, "\n\n\n\n"); /* Separates things in *Redisplay-trace* */
You can safely make it considerably larger than its default value,
if that proves inconveniently small. However, if you increase it too far,
Emacs could overflow the real C stack, and crash. */);
+ max_lisp_eval_depth = 1600;
+
+ DEFVAR_INT ("lisp-eval-depth-reserve", lisp_eval_depth_reserve,
+ doc: /* Extra depth that can be allocated to handle errors.
+This is the max depth that the system will add to `max-lisp-eval-depth'
+when calling debuggers or `handler-bind' handlers. */);
+ lisp_eval_depth_reserve = 200;
DEFVAR_LISP ("quit-flag", Vquit_flag,
doc: /* Non-nil causes `eval' to abort, unless `inhibit-quit' is non-nil.