From: Alan Mackenzie Date: Sat, 2 Sep 2023 13:50:03 +0000 (+0000) Subject: Output better error messages on certain edebug spec errors X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=1d46bca1c976b07ea99c1353a40b352e54d87364;p=emacs.git Output better error messages on certain edebug spec errors This fixes bug#65620. The error thrown up to now was "Void function edebug-after". This has been replaced by "Invalid call to `edebug-before'. Is the edebug spec for `foo' correct?". * lisp/emacs-lisp/edebug.el (edebug-b/a-error): New function which throws the new friendlier error message. (edebug-before, edebug-after): Replace the defalias's to nil with actual functions which just call edebug-b/a-error. * doc/lispref/edebug.texi (Specification List): In the entry for `sexp', warn against mistakenly using `form' for an --- diff --git a/doc/lispref/edebug.texi b/doc/lispref/edebug.texi index c5be3a40d2c..7cf7ee51751 100644 --- a/doc/lispref/edebug.texi +++ b/doc/lispref/edebug.texi @@ -1289,6 +1289,8 @@ examples): @item sexp A single unevaluated Lisp object, which is not instrumented. @c an "expression" is not necessarily intended for evaluation. +If the macro evaluates an argument at macro-expansion time, you should +use @code{sexp} for it rather than @code{form}. @item form A single evaluated expression, which is instrumented. If your macro diff --git a/lisp/emacs-lisp/edebug.el b/lisp/emacs-lisp/edebug.el index 9a06807bcdc..78326fde26d 100644 --- a/lisp/emacs-lisp/edebug.el +++ b/lisp/emacs-lisp/edebug.el @@ -2469,12 +2469,52 @@ MSG is printed after `::::} '." (setf (cdr (assq 'edebug edebug-behavior-alist)) '(edebug-default-enter edebug-fast-before edebug-fast-after))) -(defalias 'edebug-before nil +;; The following versions of `edebug-before' and `edebug-after' exist +;; to handle the error which occurs if either of them gets called +;; without an enclosing `edebug-enter'. This can happen, for example, +;; when a macro mistakenly has a `form' element in its edebug spec, +;; and it additionally, at macro-expansion time, calls `eval', +;; `apply', or `funcall' (etc.) on the corresponding argument. This +;; is intended to fix bug#65620. + +(defun edebug-b/a-error (func) + "Throw an error for an invalid call of FUNC. +FUNC is expected to be `edebug-before' or `edebug-after'." + (let (this-macro + (n 0) + bt-frame) + (while (and (setq bt-frame (backtrace-frame n)) + (not (and (car bt-frame) + (memq (cadr bt-frame) + '(macroexpand macroexpand-1))))) + (setq n (1+ n))) + (when bt-frame + (setq this-macro (caaddr bt-frame))) + + (error + (concat "Invalid call to `" (symbol-name func) "'" + (if this-macro + (concat ". Is the edebug spec for `" + (symbol-name this-macro) + "' correct?") + "" ; Not sure this case is possible (ACM, 2023-09-02) + ))))) + +(defun edebug-before (_before-index) "Function called by Edebug before a form is evaluated. -See `edebug-behavior-alist' for implementations.") -(defalias 'edebug-after nil +See `edebug-behavior-alist' for other implementations. This +version of `edebug-before' gets called when edebug is not yet set +up. `edebug-enter' binds the function cell to a real function +when edebug becomes active." + (edebug-b/a-error 'edebug-before)) + +(defun edebug-after (_before-index _after-index _form) "Function called by Edebug after a form is evaluated. -See `edebug-behavior-alist' for implementations.") +See `edebug-behavior-alist' for other implementations. This +version of `edebug-after' gets called when edebug is not yet set +up. `edebug-enter' binds the function cell to a real function +when edebug becomes active." + (edebug-b/a-error 'edebug-after)) (defun edebug--update-coverage (after-index value) (let ((old-result (aref edebug-coverage after-index)))