diff options
Diffstat (limited to 'src/eval.c')
| -rw-r--r-- | src/eval.c | 67 |
1 files changed, 6 insertions, 61 deletions
diff --git a/src/eval.c b/src/eval.c index 0cff38ce7a8..3e352911479 100644 --- a/src/eval.c +++ b/src/eval.c | |||
| @@ -57,12 +57,6 @@ Lisp_Object Vrun_hooks; | |||
| 57 | /* FIXME: We should probably get rid of this! */ | 57 | /* FIXME: We should probably get rid of this! */ |
| 58 | Lisp_Object Vsignaling_function; | 58 | Lisp_Object Vsignaling_function; |
| 59 | 59 | ||
| 60 | /* The handler structure which will catch errors in Lisp hooks called | ||
| 61 | from redisplay. We do not use it for this; we compare it with the | ||
| 62 | handler which is about to be used in signal_or_quit, and if it | ||
| 63 | matches, cause a backtrace to be generated. */ | ||
| 64 | static struct handler *redisplay_deep_handler; | ||
| 65 | |||
| 66 | /* These would ordinarily be static, but they need to be visible to GDB. */ | 60 | /* These would ordinarily be static, but they need to be visible to GDB. */ |
| 67 | bool backtrace_p (union specbinding *) EXTERNALLY_VISIBLE; | 61 | bool backtrace_p (union specbinding *) EXTERNALLY_VISIBLE; |
| 68 | Lisp_Object *backtrace_args (union specbinding *) EXTERNALLY_VISIBLE; | 62 | Lisp_Object *backtrace_args (union specbinding *) EXTERNALLY_VISIBLE; |
| @@ -244,7 +238,6 @@ init_eval (void) | |||
| 244 | lisp_eval_depth = 0; | 238 | lisp_eval_depth = 0; |
| 245 | /* This is less than the initial value of num_nonmacro_input_events. */ | 239 | /* This is less than the initial value of num_nonmacro_input_events. */ |
| 246 | when_entered_debugger = -1; | 240 | when_entered_debugger = -1; |
| 247 | redisplay_deep_handler = NULL; | ||
| 248 | } | 241 | } |
| 249 | 242 | ||
| 250 | static void | 243 | static void |
| @@ -1611,16 +1604,12 @@ internal_condition_case_n (Lisp_Object (*bfun) (ptrdiff_t, Lisp_Object *), | |||
| 1611 | ptrdiff_t nargs, | 1604 | ptrdiff_t nargs, |
| 1612 | Lisp_Object *args)) | 1605 | Lisp_Object *args)) |
| 1613 | { | 1606 | { |
| 1614 | struct handler *old_deep = redisplay_deep_handler; | ||
| 1615 | struct handler *c = push_handler (handlers, CONDITION_CASE); | 1607 | struct handler *c = push_handler (handlers, CONDITION_CASE); |
| 1616 | if (redisplaying_p) | ||
| 1617 | redisplay_deep_handler = c; | ||
| 1618 | if (sys_setjmp (c->jmp)) | 1608 | if (sys_setjmp (c->jmp)) |
| 1619 | { | 1609 | { |
| 1620 | Lisp_Object val = handlerlist->val; | 1610 | Lisp_Object val = handlerlist->val; |
| 1621 | clobbered_eassert (handlerlist == c); | 1611 | clobbered_eassert (handlerlist == c); |
| 1622 | handlerlist = handlerlist->next; | 1612 | handlerlist = handlerlist->next; |
| 1623 | redisplay_deep_handler = old_deep; | ||
| 1624 | return hfun (val, nargs, args); | 1613 | return hfun (val, nargs, args); |
| 1625 | } | 1614 | } |
| 1626 | else | 1615 | else |
| @@ -1628,7 +1617,6 @@ internal_condition_case_n (Lisp_Object (*bfun) (ptrdiff_t, Lisp_Object *), | |||
| 1628 | Lisp_Object val = bfun (nargs, args); | 1617 | Lisp_Object val = bfun (nargs, args); |
| 1629 | eassert (handlerlist == c); | 1618 | eassert (handlerlist == c); |
| 1630 | handlerlist = c->next; | 1619 | handlerlist = c->next; |
| 1631 | redisplay_deep_handler = old_deep; | ||
| 1632 | return val; | 1620 | return val; |
| 1633 | } | 1621 | } |
| 1634 | } | 1622 | } |
| @@ -1766,11 +1754,6 @@ quit (void) | |||
| 1766 | return signal_or_quit (Qquit, Qnil, true); | 1754 | return signal_or_quit (Qquit, Qnil, true); |
| 1767 | } | 1755 | } |
| 1768 | 1756 | ||
| 1769 | /* Has an error in redisplay giving rise to a backtrace occurred as | ||
| 1770 | yet in the current command? This gets reset in the command | ||
| 1771 | loop. */ | ||
| 1772 | bool backtrace_yet = false; | ||
| 1773 | |||
| 1774 | /* Signal an error, or quit. ERROR_SYMBOL and DATA are as with Fsignal. | 1757 | /* Signal an error, or quit. ERROR_SYMBOL and DATA are as with Fsignal. |
| 1775 | If CONTINUABLE, the caller allows this function to return | 1758 | If CONTINUABLE, the caller allows this function to return |
| 1776 | (presumably after calling the debugger); | 1759 | (presumably after calling the debugger); |
| @@ -1897,51 +1880,13 @@ signal_or_quit (Lisp_Object error_symbol, Lisp_Object data, bool continuable) | |||
| 1897 | return Qnil; | 1880 | return Qnil; |
| 1898 | } | 1881 | } |
| 1899 | 1882 | ||
| 1900 | /* If an error is signaled during a Lisp hook in redisplay, write a | ||
| 1901 | backtrace into the buffer *Redisplay-trace*. */ | ||
| 1902 | /* FIXME: Turn this into a `handler-bind` installed during redisplay? */ | ||
| 1903 | if (!debugger_called && !oom | ||
| 1904 | && backtrace_on_redisplay_error | ||
| 1905 | && (NILP (clause) || h == redisplay_deep_handler) | ||
| 1906 | && NILP (Vinhibit_debugger) | ||
| 1907 | && !NILP (Ffboundp (Qdebug_early))) | ||
| 1908 | { | ||
| 1909 | specpdl_ref count = SPECPDL_INDEX (); | ||
| 1910 | max_ensure_room (100); | ||
| 1911 | AUTO_STRING (redisplay_trace, "*Redisplay-trace*"); | ||
| 1912 | Lisp_Object redisplay_trace_buffer; | ||
| 1913 | AUTO_STRING (gap, "\n\n\n\n"); /* Separates things in *Redisplay-trace* */ | ||
| 1914 | Lisp_Object delayed_warning; | ||
| 1915 | redisplay_trace_buffer = Fget_buffer_create (redisplay_trace, Qnil); | ||
| 1916 | current_buffer = XBUFFER (redisplay_trace_buffer); | ||
| 1917 | if (!backtrace_yet) /* Are we on the first backtrace of the command? */ | ||
| 1918 | Ferase_buffer (); | ||
| 1919 | else | ||
| 1920 | Finsert (1, &gap); | ||
| 1921 | backtrace_yet = true; | ||
| 1922 | specbind (Qstandard_output, redisplay_trace_buffer); | ||
| 1923 | specbind (Qdebugger, Qdebug_early); | ||
| 1924 | call_debugger (list2 (Qerror, error)); | ||
| 1925 | unbind_to (count, Qnil); | ||
| 1926 | delayed_warning = make_string | ||
| 1927 | ("Error in a redisplay Lisp hook. See buffer *Redisplay-trace*", 61); | ||
| 1928 | |||
| 1929 | Vdelayed_warnings_list = Fcons (list2 (Qerror, delayed_warning), | ||
| 1930 | Vdelayed_warnings_list); | ||
| 1931 | } | ||
| 1932 | |||
| 1933 | if (!NILP (clause)) | 1883 | if (!NILP (clause)) |
| 1934 | { | 1884 | unwind_to_catch (h, NONLOCAL_EXIT_SIGNAL, error); |
| 1935 | unwind_to_catch (h, NONLOCAL_EXIT_SIGNAL, error); | 1885 | else if (handlerlist != handlerlist_sentinel) |
| 1936 | } | 1886 | /* FIXME: This will come right back here if there's no `top-level' |
| 1937 | else | 1887 | catcher. A better solution would be to abort here, and instead |
| 1938 | { | 1888 | add a catch-all condition handler so we never come here. */ |
| 1939 | if (handlerlist != handlerlist_sentinel) | 1889 | Fthrow (Qtop_level, Qt); |
| 1940 | /* FIXME: This will come right back here if there's no `top-level' | ||
| 1941 | catcher. A better solution would be to abort here, and instead | ||
| 1942 | add a catch-all condition handler so we never come here. */ | ||
| 1943 | Fthrow (Qtop_level, Qt); | ||
| 1944 | } | ||
| 1945 | 1890 | ||
| 1946 | string = Ferror_message_string (error); | 1891 | string = Ferror_message_string (error); |
| 1947 | fatal ("%s", SDATA (string)); | 1892 | fatal ("%s", SDATA (string)); |