diff options
author | Stefan Monnier <monnier@iro.umontreal.ca> | 2011-01-26 15:02:07 -0500 |
---|---|---|
committer | Stefan Monnier <monnier@iro.umontreal.ca> | 2011-01-26 15:02:07 -0500 |
commit | e7f7fbaa11828658bfa7a47e07446d050dc0ad92 (patch) | |
tree | c0f4b39a119341d02199a1d87af16d8af7409b9a /src/eval.c | |
parent | 6608a7d8fb941119faeb8873df0f56eea0ac1764 (diff) | |
download | emacs-e7f7fbaa11828658bfa7a47e07446d050dc0ad92.tar.gz |
Let the debugger continue to the normal handler.
* src/eval.c (maybe_call_debugger): Declare before new use.
(find_handler_clause): Don't call debugger any more.
Ignore Vstack_trace_on_error.
Use XCAR/XCDR.
(syms_of_eval): Remove Vstack_trace_on_error.
(Fsignal): Only modify handlerlist when we know we need to do it.
Call the debugger when necessary.
* src/globals.h (Vstack_trace_on_error): Remove.
Fixes: debbugs:7825
Diffstat (limited to 'src/eval.c')
-rw-r--r-- | src/eval.c | 153 |
1 files changed, 49 insertions, 104 deletions
diff --git a/src/eval.c b/src/eval.c index 709366717da..d0effc755a2 100644 --- a/src/eval.c +++ b/src/eval.c @@ -1557,6 +1557,8 @@ internal_condition_case_n (Lisp_Object (*bfun) (int, Lisp_Object*), static Lisp_Object find_handler_clause (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object); +static int maybe_call_debugger (Lisp_Object conditions, Lisp_Object sig, + Lisp_Object data); DEFUN ("signal", Fsignal, Ssignal, 2, 2, 0, doc: /* Signal an error. Args are ERROR-SYMBOL and associated DATA. @@ -1577,10 +1579,12 @@ See also the function `condition-case'. */) /* When memory is full, ERROR-SYMBOL is nil, and DATA is (REAL-ERROR-SYMBOL . REAL-DATA). That is a special case--don't do this in other situations. */ - register struct handler *allhandlers = handlerlist; Lisp_Object conditions; Lisp_Object string; - Lisp_Object real_error_symbol; + Lisp_Object real_error_symbol + = (NILP (error_symbol) ? Fcar (data) : error_symbol); + register Lisp_Object clause = Qnil; + struct handler *h; struct backtrace *bp; immediate_quit = handling_signal = 0; @@ -1588,11 +1592,6 @@ See also the function `condition-case'. */) if (gc_in_progress || waiting_for_input) abort (); - if (NILP (error_symbol)) - real_error_symbol = Fcar (data); - else - real_error_symbol = error_symbol; - #if 0 /* rms: I don't know why this was here, but it is surely wrong for an error that is handled. */ #ifdef HAVE_WINDOW_SYSTEM @@ -1631,49 +1630,49 @@ See also the function `condition-case'. */) Vsignaling_function = *bp->function; } - for (; handlerlist; handlerlist = handlerlist->next) + for (h = handlerlist; h; h = h->next) { - register Lisp_Object clause; - - clause = find_handler_clause (handlerlist->handler, conditions, + clause = find_handler_clause (h->handler, conditions, error_symbol, data); - - if (EQ (clause, Qlambda)) - { - /* We can't return values to code which signaled an error, but we - can continue code which has signaled a quit. */ - if (EQ (real_error_symbol, Qquit)) - return Qnil; - else - error ("Cannot return from the debugger in an error"); - } - if (!NILP (clause)) - { - Lisp_Object unwind_data; - struct handler *h = handlerlist; - - handlerlist = allhandlers; - - if (NILP (error_symbol)) - unwind_data = data; - else - unwind_data = Fcons (error_symbol, data); - h->chosen_clause = clause; - unwind_to_catch (h->tag, unwind_data); - } + break; } + + if (/* Don't run the debugger for a memory-full error. + (There is no room in memory to do that!) */ + !NILP (error_symbol) + && (!NILP (Vdebug_on_signal) + /* If no handler is present now, try to run the debugger. */ + || NILP (clause) + /* Special handler that means "print a message and run debugger + if requested". */ + || EQ (h->handler, Qerror))) + { + int debugger_called + = maybe_call_debugger (conditions, error_symbol, data); + /* We can't return values to code which signaled an error, but we + can continue code which has signaled a quit. */ + if (debugger_called && EQ (real_error_symbol, Qquit)) + return Qnil; + } - handlerlist = allhandlers; - /* If no handler is present now, try to run the debugger, - and if that fails, throw to top level. */ - find_handler_clause (Qerror, conditions, error_symbol, data); - if (catchlist != 0) - Fthrow (Qtop_level, Qt); + if (!NILP (clause)) + { + Lisp_Object unwind_data + = (NILP (error_symbol) ? data : Fcons (error_symbol, data)); + + h->chosen_clause = clause; + unwind_to_catch (h->tag, unwind_data); + } + else + { + if (catchlist != 0) + Fthrow (Qtop_level, Qt); + } if (! NILP (error_symbol)) data = Fcons (error_symbol, data); - + string = Ferror_message_string (data); fatal ("%s", SDATA (string), 0); } @@ -1848,63 +1847,24 @@ find_handler_clause (Lisp_Object handlers, Lisp_Object conditions, Lisp_Object sig, Lisp_Object data) { register Lisp_Object h; - register Lisp_Object tem; - int debugger_called = 0; - int debugger_considered = 0; /* t is used by handlers for all conditions, set up by C code. */ if (EQ (handlers, Qt)) return Qt; - /* Don't run the debugger for a memory-full error. - (There is no room in memory to do that!) */ - if (NILP (sig)) - debugger_considered = 1; - /* error is used similarly, but means print an error message and run the debugger if that is enabled. */ - if (EQ (handlers, Qerror) - || !NILP (Vdebug_on_signal)) /* This says call debugger even if - there is a handler. */ - { - if (!NILP (sig) && wants_debugger (Vstack_trace_on_error, conditions)) - { - max_lisp_eval_depth += 15; - max_specpdl_size++; - if (noninteractive) - Fbacktrace (); - else - internal_with_output_to_temp_buffer - ("*Backtrace*", - (Lisp_Object (*) (Lisp_Object)) Fbacktrace, - Qnil); - max_specpdl_size--; - max_lisp_eval_depth -= 15; - } - - if (!debugger_considered) - { - debugger_considered = 1; - debugger_called = maybe_call_debugger (conditions, sig, data); - } - - /* If there is no handler, return saying whether we ran the debugger. */ - if (EQ (handlers, Qerror)) - { - if (debugger_called) - return Qlambda; - return Qt; - } - } + if (EQ (handlers, Qerror)) + return Qt; - for (h = handlers; CONSP (h); h = Fcdr (h)) + for (h = handlers; CONSP (h); h = XCDR (h)) { - Lisp_Object handler, condit; + Lisp_Object handler = XCAR (h); + Lisp_Object condit, tem; - handler = Fcar (h); if (!CONSP (handler)) continue; - condit = Fcar (handler); + condit = XCAR (handler); /* Handle a single condition name in handler HANDLER. */ if (SYMBOLP (condit)) { @@ -1918,15 +1878,9 @@ find_handler_clause (Lisp_Object handlers, Lisp_Object conditions, Lisp_Object tail; for (tail = condit; CONSP (tail); tail = XCDR (tail)) { - tem = Fmemq (Fcar (tail), conditions); + tem = Fmemq (XCAR (tail), conditions); if (!NILP (tem)) - { - /* This handler is going to apply. - Does it allow the debugger to run first? */ - if (! debugger_considered && !NILP (Fmemq (Qdebug, condit))) - maybe_call_debugger (conditions, sig, data); - return handler; - } + return handler; } } } @@ -1943,7 +1897,6 @@ verror (const char *m, va_list ap) EMACS_INT size = 200; int mlen; char *buffer = buf; - char *args[3]; int allocated = 0; Lisp_Object string; @@ -3523,14 +3476,6 @@ before making `inhibit-quit' nil. */); Qdebug = intern_c_string ("debug"); staticpro (&Qdebug); - DEFVAR_LISP ("stack-trace-on-error", Vstack_trace_on_error, - doc: /* *Non-nil means errors display a backtrace buffer. -More precisely, this happens for any error that is handled -by the editor command loop. -If the value is a list, an error only means to display a backtrace -if one of its condition symbols appears in the list. */); - Vstack_trace_on_error = Qnil; - DEFVAR_LISP ("debug-on-error", Vdebug_on_error, doc: /* *Non-nil means enter debugger if an error is signaled. Does not apply to errors handled by `condition-case' or those |