Commit 9f5903bb authored by Richard M. Stallman's avatar Richard M. Stallman
Browse files

(call_debugger): Take full care of extending stack limits

to make space for the debugger, and restore the change afterward.
Bind debug-on-error to nil.
(restore_stack_limits): New subroutine.
(Fsignal): Extend specpdl bound along with eval depth bound,
for calling edebug.  Don't do either one, for calling debugger.
(find_handler_clause): Don't bind debug-on-error here.
Don't unbind anything either.
Temporarily advance max_specpdl_size for calling
internal_with_output_to_temp_buffer.
(grow_specpdl): Don't alter max_specpdl_size before signaling an error.
(syms_of_eval) <max-specpdl-size>: Doc fix.
parent 7bbae30c
......@@ -227,6 +227,18 @@ init_eval ()
when_entered_debugger = -1;
}
/* unwind-protect function used by call_debugger. */
static Lisp_Object
restore_stack_limits (data)
Lisp_Object data;
{
max_specpdl_size = XINT (XCAR (data));
max_lisp_eval_depth = XINT (XCDR (data));
}
/* Call the Lisp debugger, giving it argument ARG. */
Lisp_Object
call_debugger (arg)
Lisp_Object arg;
......@@ -234,12 +246,22 @@ call_debugger (arg)
int debug_while_redisplaying;
int count = SPECPDL_INDEX ();
Lisp_Object val;
int old_max = max_specpdl_size;
if (lisp_eval_depth + 20 > max_lisp_eval_depth)
max_lisp_eval_depth = lisp_eval_depth + 20;
/* Temporarily bump up the stack limits,
so the debugger won't run out of stack. */
if (specpdl_size + 40 > max_specpdl_size)
max_specpdl_size = specpdl_size + 40;
max_specpdl_size += 1;
record_unwind_protect (restore_stack_limits,
Fcons (make_number (old_max),
make_number (max_lisp_eval_depth)));
max_specpdl_size = old_max;
if (lisp_eval_depth + 40 > max_lisp_eval_depth)
max_lisp_eval_depth = lisp_eval_depth + 40;
if (SPECPDL_INDEX () + 100 > max_specpdl_size)
max_specpdl_size = SPECPDL_INDEX () + 100;
#ifdef HAVE_X_WINDOWS
if (display_hourglass_p)
......@@ -256,6 +278,7 @@ call_debugger (arg)
specbind (intern ("debugger-may-continue"),
debug_while_redisplaying ? Qnil : Qt);
specbind (Qinhibit_redisplay, Qnil);
specbind (Qdebug_on_error, Qnil);
#if 0 /* Binding this prevents execution of Lisp code during
redisplay, which necessarily leads to display problems. */
......@@ -1533,7 +1556,16 @@ See also the function `condition-case'. */)
/* This hook is used by edebug. */
if (! NILP (Vsignal_hook_function)
&& ! NILP (error_symbol))
call2 (Vsignal_hook_function, error_symbol, data);
{
/* Edebug takes care of restoring these variables when it exits. */
if (lisp_eval_depth + 20 > max_lisp_eval_depth)
max_lisp_eval_depth = lisp_eval_depth + 20;
if (SPECPDL_INDEX () + 40 > max_specpdl_size)
max_specpdl_size = SPECPDL_INDEX () + 40;
call2 (Vsignal_hook_function, error_symbol, data);
}
conditions = Fget (real_error_symbol, Qerror_conditions);
......@@ -1555,12 +1587,6 @@ See also the function `condition-case'. */)
{
register Lisp_Object clause;
if (lisp_eval_depth + 20 > max_lisp_eval_depth)
max_lisp_eval_depth = lisp_eval_depth + 20;
if (specpdl_size + 40 > max_specpdl_size)
max_specpdl_size = specpdl_size + 40;
clause = find_handler_clause (handlerlist->handler, conditions,
error_symbol, data, &debugger_value);
......@@ -1673,7 +1699,11 @@ skip_debugger (conditions, data)
= SIG is nil, and DATA is (SYMBOL . REST-OF-DATA).
This is for memory-full errors only.
Store value returned from debugger into *DEBUGGER_VALUE_PTR. */
Store value returned from debugger into *DEBUGGER_VALUE_PTR.
We need to increase max_specpdl_size temporarily around
anything we do that can push on the specpdl, so as not to get
a second error here in case we're handling specpdl overflow. */
static Lisp_Object
find_handler_clause (handlers, conditions, sig, data, debugger_value_ptr)
......@@ -1691,7 +1721,6 @@ find_handler_clause (handlers, conditions, sig, data, debugger_value_ptr)
|| !NILP (Vdebug_on_signal)) /* This says call debugger even if
there is a handler. */
{
int count = SPECPDL_INDEX ();
int debugger_called = 0;
Lisp_Object sig_symbol, combined_data;
/* This is set to 1 if we are handling a memory-full error,
......@@ -1713,6 +1742,7 @@ find_handler_clause (handlers, conditions, sig, data, debugger_value_ptr)
if (wants_debugger (Vstack_trace_on_error, conditions))
{
max_specpdl_size++;
#ifdef PROTOTYPES
internal_with_output_to_temp_buffer ("*Backtrace*",
(Lisp_Object (*) (Lisp_Object)) Fbacktrace,
......@@ -1721,6 +1751,7 @@ find_handler_clause (handlers, conditions, sig, data, debugger_value_ptr)
internal_with_output_to_temp_buffer ("*Backtrace*",
Fbacktrace, Qnil);
#endif
max_specpdl_size--;
}
if (! no_debugger
&& (EQ (sig_symbol, Qquit)
......@@ -1729,7 +1760,6 @@ find_handler_clause (handlers, conditions, sig, data, debugger_value_ptr)
&& ! skip_debugger (conditions, combined_data)
&& when_entered_debugger < num_nonmacro_input_events)
{
specbind (Qdebug_on_error, Qnil);
*debugger_value_ptr
= call_debugger (Fcons (Qerror,
Fcons (combined_data, Qnil)));
......@@ -1739,7 +1769,7 @@ find_handler_clause (handlers, conditions, sig, data, debugger_value_ptr)
if (EQ (handlers, Qerror))
{
if (debugger_called)
return unbind_to (count, Qlambda);
return Qlambda;
return Qt;
}
}
......@@ -3019,13 +3049,8 @@ grow_specpdl ()
if (max_specpdl_size < 400)
max_specpdl_size = 400;
if (specpdl_size >= max_specpdl_size)
{
if (!NILP (Vdebug_on_error))
/* Leave room for some specpdl in the debugger. */
max_specpdl_size = specpdl_size + 100;
Fsignal (Qerror,
Fcons (build_string ("Variable binding depth exceeds max-specpdl-size"), Qnil));
}
Fsignal (Qerror,
Fcons (build_string ("Variable binding depth exceeds max-specpdl-size"), Qnil));
}
specpdl_size *= 2;
if (specpdl_size > max_specpdl_size)
......@@ -3333,7 +3358,7 @@ syms_of_eval ()
{
DEFVAR_INT ("max-specpdl-size", &max_specpdl_size,
doc: /* *Limit on number of Lisp variable bindings & unwind-protects.
If Lisp code tries to make more than this many at once,
If Lisp code tries to increase the total number past this amount,
an error is signaled.
You can safely use a value considerably larger than the default value,
if that proves inconveniently small. However, if you increase it too far,
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment