#include "commands.h"
#include "keyboard.h"
#include "dispextern.h"
-#include "frame.h" /* For XFRAME. */
-
-#if HAVE_X_WINDOWS
-#include "xterm.h"
-#endif
/* Chain of condition and catch handlers currently in effect. */
max_lisp_eval_depth = XINT (XCDR (data));
}
+static void grow_specpdl (void);
+
/* Call the Lisp debugger, giving it argument ARG. */
Lisp_Object
bool debug_while_redisplaying;
ptrdiff_t count = SPECPDL_INDEX ();
Lisp_Object val;
- EMACS_INT old_max = max_specpdl_size;
-
- /* Temporarily bump up the stack limits,
- so the debugger won't run out of stack. */
-
- 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;
+ EMACS_INT old_depth = max_lisp_eval_depth;
+ /* Do not allow max_specpdl_size less than actual depth (Bug#16603). */
+ EMACS_INT old_max = max (max_specpdl_size, count);
if (lisp_eval_depth + 40 > max_lisp_eval_depth)
max_lisp_eval_depth = lisp_eval_depth + 40;
- if (max_specpdl_size - 100 < SPECPDL_INDEX ())
- max_specpdl_size = SPECPDL_INDEX () + 100;
+ /* While debugging Bug#16603, previous value of 100 was found
+ too small to avoid specpdl overflow in the debugger itself. */
+ if (max_specpdl_size - 200 < count)
+ max_specpdl_size = count + 200;
+
+ if (old_max == count)
+ {
+ /* We can enter the debugger due to specpdl overflow (Bug#16603). */
+ specpdl_ptr--;
+ grow_specpdl ();
+ }
+
+ /* Restore limits after leaving the debugger. */
+ record_unwind_protect (restore_stack_limits,
+ Fcons (make_number (old_max),
+ make_number (old_depth)));
#ifdef HAVE_WINDOW_SYSTEM
if (display_hourglass_p)
eassert (handlerlist == catch);
- byte_stack_list = catch->byte_stack;
gcprolist = catch->gcpro;
#ifdef DEBUG_GCPRO
gcpro_level = gcprolist ? gcprolist->level + 1 : 0;
struct handler *h;
immediate_quit = 0;
- abort_on_gc = 0;
- if (gc_in_progress || waiting_for_input)
+ if (waiting_for_input)
emacs_abort ();
#if 0 /* rms: I don't know why this was here,
&& !AUTOLOADP (XSYMBOL (function)->function))
return Qnil;
- if (!NILP (Vpurify_flag) && EQ (docstring, make_number (0)))
- /* `read1' in lread.c has found the docstring starting with "\
- and assumed the docstring will be provided by Snarf-documentation, so it
- passed us 0 instead. But that leads to accidental sharing in purecopy's
- hash-consing, so we use a (hopefully) unique integer instead. */
- docstring = make_number (XHASH (function));
return Fdefalias (function,
list5 (Qautoload, file, docstring, interactive, type),
Qnil);
args_left = original_args;
numargs = Flength (args_left);
- check_cons_list ();
-
if (XINT (numargs) < XSUBR (fun)->min_args
|| (XSUBR (fun)->max_args >= 0
&& XSUBR (fun)->max_args < XINT (numargs)))
else
xsignal1 (Qinvalid_function, original_fun);
}
- check_cons_list ();
lisp_eval_depth--;
if (backtrace_debug_on_exit (specpdl_ptr - 1))
if (debug_on_next_call)
do_debug_on_call (Qlambda);
- check_cons_list ();
-
original_fun = args[0];
retry:
else if (EQ (funcar, Qautoload))
{
Fautoload_do_load (fun, original_fun, Qnil);
- check_cons_list ();
goto retry;
}
else
xsignal1 (Qinvalid_function, original_fun);
}
- check_cons_list ();
lisp_eval_depth--;
if (backtrace_debug_on_exit (specpdl_ptr - 1))
val = call_debugger (list2 (Qexit, val));
}
\f
-void
-mark_specpdl (void)
-{
- union specbinding *pdl;
- for (pdl = specpdl; pdl != specpdl_ptr; pdl++)
- {
- switch (pdl->kind)
- {
- case SPECPDL_UNWIND:
- mark_object (specpdl_arg (pdl));
- break;
-
- case SPECPDL_BACKTRACE:
- {
- ptrdiff_t nargs = backtrace_nargs (pdl);
- mark_object (backtrace_function (pdl));
- if (nargs == UNEVALLED)
- nargs = 1;
- while (nargs--)
- mark_object (backtrace_args (pdl)[nargs]);
- }
- break;
-
- case SPECPDL_LET_DEFAULT:
- case SPECPDL_LET_LOCAL:
- mark_object (specpdl_where (pdl));
- /* Fall through. */
- case SPECPDL_LET:
- mark_object (specpdl_symbol (pdl));
- mark_object (specpdl_old_value (pdl));
- break;
- }
- }
-}
-
void
get_backtrace (Lisp_Object array)
{
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,
-Emacs could run out of memory trying to make the stack bigger. */);
+Emacs could run out of memory trying to make the stack bigger.
+Note that this limit may be silently increased by the debugger
+if `debug-on-error' or `debug-on-quit' is set. */);
DEFVAR_INT ("max-lisp-eval-depth", max_lisp_eval_depth,
doc: /* Limit on depth in `eval', `apply' and `funcall' before error.