From: Stefan Monnier Date: Wed, 26 Jan 2011 20:02:07 +0000 (-0500) Subject: Let the debugger continue to the normal handler. X-Git-Tag: emacs-pretest-24.0.90~104^2~618^2~1322^2~122 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=e7f7fbaa11828658bfa7a47e07446d050dc0ad92;p=emacs.git 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 --- diff --git a/etc/NEWS b/etc/NEWS index 0a12a122d27..da9f1aa3ac1 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -692,6 +692,11 @@ sc.el, x-menu.el, rnews.el, rnewspost.el * Lisp changes in Emacs 24.1 +** Removed the stack-trace-on-error variable. +Also the debugger can now "continue" from an error, which means it will jump +to the error handler as if the debugger had not been invoked instead of +jumping all the way to the top-level. + ** New function `read-char-choice' reads a restricted set of characters, discarding any inputs not inside the set. diff --git a/lisp/cus-start.el b/lisp/cus-start.el index f89a5b37ff0..d2d99ee64fb 100644 --- a/lisp/cus-start.el +++ b/lisp/cus-start.el @@ -166,12 +166,6 @@ Leaving \"Default\" unchecked is equivalent with specifying a default of (max-mini-window-height limits (choice (const :tag "quarter screen" nil) number) "23.1") - (stack-trace-on-error debug - (choice (const :tag "off") - (repeat :menu-tag "When" - :value (nil) - (symbol :format "%v")) - (const :tag "always" t))) (debug-on-error debug (choice (const :tag "off") (repeat :menu-tag "When" diff --git a/src/ChangeLog b/src/ChangeLog index 2041b5bb45c..62782e63eef 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,15 @@ +2011-01-26 Stefan Monnier + + Let the debugger continue to the normal handler (bug#7825). + * 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. + * globals.h (Vstack_trace_on_error): Remove. + 2011-01-26 Chong Yidong * font.c (font_parse_fcname): Rewrite GTK font name parser. 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 diff --git a/src/globals.h b/src/globals.h index 3d7203b875a..5dc2d540409 100644 --- a/src/globals.h +++ b/src/globals.h @@ -434,10 +434,6 @@ struct emacs_globals continue the interrupted redisplay. */ int f_debugger_may_continue; - /* List of conditions (non-nil atom means all) which cause a backtrace - if an error is handled by the command loop's error handler. */ - Lisp_Object f_Vstack_trace_on_error; - /* List of conditions (non-nil atom means all) which enter the debugger if an error is handled by the command loop's error handler. */ Lisp_Object f_Vdebug_on_error; @@ -2326,8 +2322,6 @@ extern struct emacs_globals globals; globals.f_Vsource_directory #define Vspecial_event_map \ globals.f_Vspecial_event_map -#define Vstack_trace_on_error \ - globals.f_Vstack_trace_on_error #define Vstandard_display_table \ globals.f_Vstandard_display_table #define Vstandard_input \