Mercurial > hg > xemacs-beta
changeset 2532:989a7680c221
[xemacs-hg @ 2005-01-29 09:15:55 by ben]
Add backtrace when throwing past call_trapping_problems()
alloc.c, backtrace.h, bytecode.c, cmdloop.c, eval.c, lisp.h, macros.c: Also include a backtrace when we catch an attempt to throw outside
of a function where call_trapping_problems() has been used.
author | ben |
---|---|
date | Sat, 29 Jan 2005 09:16:00 +0000 |
parents | 7de8d9ab7bbd |
children | 0e56a4a4b77f |
files | src/ChangeLog src/alloc.c src/backtrace.h src/bytecode.c src/cmdloop.c src/eval.c src/lisp.h src/macros.c |
diffstat | 8 files changed, 76 insertions(+), 31 deletions(-) [+] |
line wrap: on
line diff
--- a/src/ChangeLog Sat Jan 29 09:06:40 2005 +0000 +++ b/src/ChangeLog Sat Jan 29 09:16:00 2005 +0000 @@ -1,3 +1,27 @@ +2005-01-29 Ben Wing <ben@xemacs.org> + + * alloc.c (garbage_collect_1): + * backtrace.h: + * bytecode.c (execute_rare_opcode): + * cmdloop.c: + * cmdloop.c (initial_command_loop): + * cmdloop.c (Frecursive_edit): + * cmdloop.c (call_command_loop): + * eval.c: + * eval.c (call_debugger): + * eval.c (Fcatch): + * eval.c (internal_catch): + * eval.c (throw_or_bomb_out): + * eval.c (condition_case_1): + * eval.c (maybe_get_trapping_problems_backtrace): + * eval.c (flagged_a_squirmer): + * eval.c (issue_call_trapping_problems_warning): + * eval.c (call_trapping_problems): + * lisp.h: + * macros.c (Fexecute_kbd_macro): + Also include a backtrace when we catch an attempt to throw outside + of a function where call_trapping_problems() has been used. + 2005-01-29 Ben Wing <ben@xemacs.org> * file-coding.c (snarf_coding_system):
--- a/src/alloc.c Sat Jan 29 09:06:40 2005 +0000 +++ b/src/alloc.c Sat Jan 29 09:16:00 2005 +0000 @@ -4775,6 +4775,7 @@ mark_object (catch->tag); mark_object (catch->val); mark_object (catch->actual_tag); + mark_object (catch->backtrace); } }
--- a/src/backtrace.h Sat Jan 29 09:06:40 2005 +0000 +++ b/src/backtrace.h Sat Jan 29 09:16:00 2005 +0000 @@ -141,6 +141,8 @@ /* Stores the actual tag used in `throw'; the same as TAG, unless TAG is Vcatch_everything_tag. */ Lisp_Object actual_tag; + /* A backtrace prior to the throw, used with Vcatch_everything_tag. */ + Lisp_Object backtrace; Lisp_Object val; struct catchtag *next; struct gcpro *gcpro;
--- a/src/bytecode.c Sat Jan 29 09:06:40 2005 +0000 +++ b/src/bytecode.c Sat Jan 29 09:16:00 2005 +0000 @@ -1377,7 +1377,7 @@ case Bcatch: { Lisp_Object arg = POP; - TOP = internal_catch (TOP, Feval, arg, 0, 0); + TOP = internal_catch (TOP, Feval, arg, 0, 0, 0); break; }
--- a/src/cmdloop.c Sat Jan 29 09:06:40 2005 +0000 +++ b/src/cmdloop.c Sat Jan 29 09:16:00 2005 +0000 @@ -1,6 +1,6 @@ /* Editor command loop. Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc. - Copyright (C) 1995, 1996, 2001, 2002 Ben Wing. + Copyright (C) 1995, 1996, 2001, 2002, 2003 Ben Wing. This file is part of XEmacs. @@ -290,7 +290,7 @@ Otherwise, this function will return normally when all command- line arguments have been processed, the user's initialization file has been read in, and the first frame has been created. */ - internal_catch (Qtop_level, top_level_1, Qnil, 0, 0); + internal_catch (Qtop_level, top_level_1, Qnil, 0, 0, 0); /* If an error occurred during startup and the initial console wasn't created, then die now (the error was already printed out @@ -310,7 +310,7 @@ MARK_MODELINE_CHANGED; /* Now invoke the command loop. It never returns; however, a throw to 'top-level will place us at the end of this loop. */ - internal_catch (Qtop_level, command_loop_2, Qnil, 0, 0); + internal_catch (Qtop_level, command_loop_2, Qnil, 0, 0, 0); /* #### wrong with selected-console? */ /* We don't actually call clear_echo_area() here, partially at least because that runs Lisp code and it may be unsafe @@ -373,7 +373,7 @@ specbind (Qstandard_output, Qt); specbind (Qstandard_input, Qt); - val = internal_catch (Qexit, command_loop_2, Qnil, 0, 0); + val = internal_catch (Qexit, command_loop_2, Qnil, 0, 0, 0); if (EQ (val, Qt)) /* Turn abort-recursive-edit into a quit. */ @@ -440,8 +440,7 @@ if (NILP (catch_errors)) Fcommand_loop_1 (); else - internal_catch (Qtop_level, - cold_load_command_loop, Qnil, 0, 0); + internal_catch (Qtop_level, cold_load_command_loop, Qnil, 0, 0, 0); goto loop; RETURN_NOT_REACHED (Qnil); }
--- a/src/eval.c Sat Jan 29 09:06:40 2005 +0000 +++ b/src/eval.c Sat Jan 29 09:16:00 2005 +0000 @@ -404,6 +404,7 @@ #endif static int warning_will_be_discarded (Lisp_Object level); +static Lisp_Object maybe_get_trapping_problems_backtrace (void); /************************************************************************/ @@ -526,7 +527,7 @@ max_specpdl_size = specpdl_size + 40; speccount = internal_bind_int (&entering_debugger, 1); - val = internal_catch (Qdebugger, call_debugger_259, arg, &threw, 0); + val = internal_catch (Qdebugger, call_debugger_259, arg, &threw, 0, 0); return unbind_to_1 (speccount, ((threw) ? Qunbound /* Not returning a value */ @@ -1480,7 +1481,7 @@ /* This function can GC */ Lisp_Object tag = Feval (XCAR (args)); Lisp_Object body = XCDR (args); - return internal_catch (tag, Fprogn, body, 0, 0); + return internal_catch (tag, Fprogn, body, 0, 0, 0); } /* Set up a catch, then call C function FUNC on argument ARG. @@ -1492,7 +1493,8 @@ Lisp_Object (*func) (Lisp_Object arg), Lisp_Object arg, int * volatile threw, - Lisp_Object * volatile thrown_tag) + Lisp_Object * volatile thrown_tag, + Lisp_Object * volatile backtrace_before_throw) { /* This structure is made part of the chain `catchlist'. */ struct catchtag c; @@ -1501,6 +1503,7 @@ c.next = catchlist; c.tag = tag; c.actual_tag = Qnil; + c.backtrace = Qnil; c.val = Qnil; c.backlist = backtrace_list; #if 0 /* FSFmacs */ @@ -1521,6 +1524,7 @@ /* Throw works by a longjmp that comes right here. */ if (threw) *threw = 1; if (thrown_tag) *thrown_tag = c.actual_tag; + if (backtrace_before_throw) *backtrace_before_throw = c.backtrace; return c.val; } c.val = (*func) (arg); @@ -1677,6 +1681,8 @@ #endif for (c = catchlist; c; c = c->next) { + if (EQ (c->tag, Vcatch_everything_tag)) + c->backtrace = maybe_get_trapping_problems_backtrace (); if (EQ (c->tag, tag) || EQ (c->tag, Vcatch_everything_tag)) unwind_to_catch (c, val, tag); } @@ -1881,6 +1887,7 @@ #endif c.val = Qnil; c.actual_tag = Qnil; + c.backtrace = Qnil; c.backlist = backtrace_list; #if 0 /* FSFmacs */ /* #### */ @@ -4813,19 +4820,13 @@ void *arg; }; -static DECLARE_DOESNT_RETURN_TYPE - (Lisp_Object, flagged_a_squirmer (Lisp_Object, Lisp_Object, Lisp_Object)); - -static DOESNT_RETURN_TYPE (Lisp_Object) -flagged_a_squirmer (Lisp_Object error_conditions, Lisp_Object data, - Lisp_Object opaque) -{ - struct call_trapping_problems *p = - (struct call_trapping_problems *) get_opaque_ptr (opaque); +static Lisp_Object +maybe_get_trapping_problems_backtrace (void) +{ + Lisp_Object backtrace; if (!(inhibit_flags & INHIBIT_WARNING_ISSUE) - && !warning_will_be_discarded (current_warning_level ()) - && !EQ (error_conditions, Qquit)) + && !warning_will_be_discarded (current_warning_level ())) { struct gcpro gcpro1; Lisp_Object lstream = Qnil; @@ -4842,15 +4843,32 @@ lstream = make_resizing_buffer_output_stream (); Fbacktrace (lstream, Qt); Lstream_flush (XLSTREAM (lstream)); - p->backtrace = resizing_buffer_to_lisp_string (XLSTREAM (lstream)); + backtrace = resizing_buffer_to_lisp_string (XLSTREAM (lstream)); Lstream_delete (XLSTREAM (lstream)); UNGCPRO; unbind_to (speccount); } else + backtrace = Qnil; + + return backtrace; +} + +static DECLARE_DOESNT_RETURN_TYPE + (Lisp_Object, flagged_a_squirmer (Lisp_Object, Lisp_Object, Lisp_Object)); + +static DOESNT_RETURN_TYPE (Lisp_Object) +flagged_a_squirmer (Lisp_Object error_conditions, Lisp_Object data, + Lisp_Object opaque) +{ + struct call_trapping_problems *p = + (struct call_trapping_problems *) get_opaque_ptr (opaque); + + if (!EQ (error_conditions, Qquit)) + p->backtrace = maybe_get_trapping_problems_backtrace (); + else p->backtrace = Qnil; - p->error_conditions = error_conditions; p->data = data; @@ -4891,11 +4909,11 @@ { Lisp_Object errstr = emacs_sprintf_string_lisp - ("%s: Attempt to throw outside of function " - "to catch `%s' with value `%s'", + ("%s: Attempt to throw outside of function:" + "To catch `%s' with value `%s'\n\nBacktrace follows:\n\n%s", Qnil, 3, build_msg_string (warning_string ? warning_string : "error"), - p->thrown_tag, p->thrown_value); + p->thrown_tag, p->thrown_value, p->backtrace); warn_when_safe_lispobj (Qerror, current_warning_level (), errstr); } else if (p->caught_error && !EQ (p->error_conditions, Qquit)) @@ -5109,7 +5127,7 @@ struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5; struct call_trapping_problems package; struct call_trapping_problems_result real_problem; - Lisp_Object opaque, thrown_tag, tem; + Lisp_Object opaque, thrown_tag, tem, thrown_backtrace; int thrown = 0; assert (SYMBOLP (warning_class)); /* sanity-check */ @@ -5144,11 +5162,11 @@ after printing the warning. (We print the warning in the stack context of the error, so we can get a backtrace.) */ tem = internal_catch (package.catchtag, call_trapping_problems_1, opaque, - &thrown, &thrown_tag); + &thrown, &thrown_tag, &thrown_backtrace); else if (flags & INTERNAL_INHIBIT_THROWS) /* We skip over the first wrapper, which traps errors. */ tem = internal_catch (package.catchtag, call_trapping_problems_2, opaque, - &thrown, &thrown_tag); + &thrown, &thrown_tag, &thrown_backtrace); else /* Nothing special. */ tem = (fun) (arg); @@ -5182,7 +5200,7 @@ problem->caught_throw = 1; problem->error_conditions = Qnil; problem->data = Qnil; - problem->backtrace = Qnil; + problem->backtrace = thrown_backtrace; problem->thrown_tag = thrown_tag; problem->thrown_value = tem; }
--- a/src/lisp.h Sat Jan 29 09:06:40 2005 +0000 +++ b/src/lisp.h Sat Jan 29 09:16:00 2005 +0000 @@ -4158,6 +4158,7 @@ int proper_redisplay_wrapping_in_place (void); Lisp_Object internal_catch (Lisp_Object, Lisp_Object (*) (Lisp_Object), Lisp_Object, int * volatile, + Lisp_Object * volatile, Lisp_Object * volatile); Lisp_Object condition_case_1 (Lisp_Object, Lisp_Object (*) (Lisp_Object),
--- a/src/macros.c Sat Jan 29 09:06:40 2005 +0000 +++ b/src/macros.c Sat Jan 29 09:16:00 2005 +0000 @@ -278,7 +278,7 @@ executing_macro_index = 0; con->prefix_arg = Qnil; internal_catch (Qexecute_kbd_macro, call_command_loop, - Qnil, 0, 0); + Qnil, 0, 0, 0); } while (--repeat != 0 && (STRINGP (Vexecuting_macro) ||