mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-06-14 12:31:25 +00:00
Support Elisp debugging and backtraces in code called by modules
* src/lisp.h (handlertype) <CATCHER_ALL_DEBUGGABLE>: New enumeration value. * src/emacs-module.c (MODULE_HANDLE_NONLOCAL_EXIT): * src/eval.c (Fthrow, signal_or_quit): Use it. * test/src/emacs-module-tests.el (mod-test-non-local-exit-funcall-debug-on-error): New test. Bug#80714 Copyright-paperwork-exempt: yes.
This commit is contained in:
parent
1cfbad0188
commit
e4633e657a
4 changed files with 18 additions and 4 deletions
|
|
@ -263,13 +263,11 @@ module_memory_buffer_too_small (ptrdiff_t actual, ptrdiff_t required)
|
|||
code after the macro may longjmp back into the macro, which means
|
||||
its local variable INTERNAL_CLEANUP must stay live in later code. */
|
||||
|
||||
/* TODO: Make backtraces work if this macro is used. */
|
||||
|
||||
#define MODULE_HANDLE_NONLOCAL_EXIT(retval) \
|
||||
if (module_non_local_exit_check (env) != emacs_funcall_exit_return) \
|
||||
return retval; \
|
||||
struct handler *internal_handler = \
|
||||
push_handler_nosignal (Qt, CATCHER_ALL); \
|
||||
push_handler_nosignal (Qt, CATCHER_ALL_DEBUGGABLE); \
|
||||
if (!internal_handler) \
|
||||
{ \
|
||||
module_out_of_memory (env); \
|
||||
|
|
|
|||
|
|
@ -1453,7 +1453,7 @@ Both TAG and VALUE are evalled. */
|
|||
if (!NILP (tag))
|
||||
for (c = handlerlist; c; c = c->next)
|
||||
{
|
||||
if (c->type == CATCHER_ALL)
|
||||
if (c->type == CATCHER_ALL || c->type == CATCHER_ALL_DEBUGGABLE)
|
||||
unwind_to_catch (c, NONLOCAL_EXIT_THROW, Fcons (tag, value));
|
||||
if (c->type == CATCHER && EQ (c->tag_or_ch, tag))
|
||||
unwind_to_catch (c, NONLOCAL_EXIT_THROW, value);
|
||||
|
|
@ -1981,6 +1981,9 @@ signal_or_quit (Lisp_Object error_symbol, Lisp_Object data, bool continuable)
|
|||
case CATCHER_ALL:
|
||||
clause = Qt;
|
||||
break;
|
||||
case CATCHER_ALL_DEBUGGABLE:
|
||||
clause = Qdebug;
|
||||
break;
|
||||
case CATCHER:
|
||||
continue;
|
||||
case CONDITION_CASE:
|
||||
|
|
@ -2024,6 +2027,7 @@ signal_or_quit (Lisp_Object error_symbol, Lisp_Object data, bool continuable)
|
|||
|| NILP (clause)
|
||||
/* A `debug' symbol in the handler list disables the normal
|
||||
suppression of the debugger. */
|
||||
|| EQ (clause, Qdebug)
|
||||
|| (CONSP (clause) && !NILP (Fmemq (Qdebug, clause)))
|
||||
/* Special handler that means "print a message and run debugger
|
||||
if requested". */
|
||||
|
|
|
|||
|
|
@ -3810,6 +3810,8 @@ enum handlertype {
|
|||
CATCHER_ALL, /* Wildcard that catches all throws and signals.
|
||||
'tag_or_ch' is unused.
|
||||
'val' holds the retval during longjmp. */
|
||||
CATCHER_ALL_DEBUGGABLE, /* Like CATCHER_ALL, but does not suppress the
|
||||
debugger. */
|
||||
HANDLER_BIND, /* Entry for 'handler-bind'.
|
||||
'tag_or_ch' holds the list of conditions.
|
||||
'val' holds the handler function.
|
||||
|
|
|
|||
|
|
@ -146,6 +146,16 @@ changes."
|
|||
(should (equal (mod-test-non-local-exit-funcall (lambda () (throw 'tag 32)))
|
||||
'(throw tag 32))))
|
||||
|
||||
(ert-deftest mod-test-non-local-exit-funcall-debug-on-error ()
|
||||
(let* ((debugger-entered nil)
|
||||
(debugger (lambda (&rest _) (setq debugger-entered t))))
|
||||
(should (equal
|
||||
(let ((debug-on-error t))
|
||||
(mod-test-non-local-exit-funcall
|
||||
(lambda () (error "test error"))))
|
||||
'(signal error ("test error"))))
|
||||
(should debugger-entered)))
|
||||
|
||||
;;; String tests
|
||||
|
||||
(defun multiply-string (s n)
|
||||
|
|
|
|||
Loading…
Reference in a new issue