summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLars Ingebrigtsen <larsi@gnus.org>2022-05-01 13:40:13 +0200
committerLars Ingebrigtsen <larsi@gnus.org>2022-05-01 13:40:13 +0200
commit7c8bec9e1ffe087918f6f218fc4560fc968aebb2 (patch)
tree2546ec6c38b293890826a0b93e2f66a2ea8f7e2f
parent81ce4b0e4ee18520f174cc5b46219e4475fcc956 (diff)
downloademacs-7c8bec9e1ffe087918f6f218fc4560fc968aebb2.tar.gz
Don't enter the debugger from *Backtrace* or edebug on eval errors
* doc/lispref/debugging.texi (Error Debugging): Document it. * doc/lispref/edebug.texi (Edebug Eval): Mention it. * lisp/emacs-lisp/debug.el (debug-allow-recursive-debug): New user option (bug#36145). (debugger-eval-expression): Use it. * lisp/emacs-lisp/edebug.el (edebug-eval-expression): Ditto. This patch is based on a patch by Noam Postavsky.
-rw-r--r--doc/lispref/debugging.texi18
-rw-r--r--doc/lispref/edebug.texi8
-rw-r--r--etc/NEWS8
-rw-r--r--lisp/emacs-lisp/debug.el13
-rw-r--r--lisp/emacs-lisp/edebug.el5
5 files changed, 47 insertions, 5 deletions
diff --git a/doc/lispref/debugging.texi b/doc/lispref/debugging.texi
index c258a9adc0e..058c9319544 100644
--- a/doc/lispref/debugging.texi
+++ b/doc/lispref/debugging.texi
@@ -196,6 +196,17 @@ echo area. For example, this can be useful when trying to find the
cause of a particular message.
@end defvar
+@defvar debug-allow-recursive-debug
+You can evaluate forms in the current stack frame in the
+@samp{*Backtrace*} buffer with the @key{e} command, and while
+edebugging you can use the @key{e} and @key{C-x C-e} commands to do
+something similar. By default, the debugger is inhibited by these
+commands (because (re-)entering the debugger at this point will
+usually take you out of the debugging context you're in). Set
+@code{debug-allow-recursive-debug} to a non-@code{nil} value to allow
+these commands to enter the debugger recursively.
+@end defvar
+
To debug an error that happens during loading of the init
file, use the option @samp{--debug-init}. This binds
@code{debug-on-error} to @code{t} while loading the init file, and
@@ -520,6 +531,7 @@ Flag the current frame like @kbd{b}. Then continue execution like
@kbd{c}, but temporarily disable break-on-entry for all functions that
are set up to do so by @code{debug-on-entry}.
+@vindex debug-allow-recursive-debug
@item e
Read a Lisp expression in the minibuffer, evaluate it (with the
relevant lexical environment, if applicable), and print the
@@ -528,7 +540,11 @@ variables, and the current buffer, as part of its operation; @kbd{e}
temporarily restores their values from outside the debugger, so you can
examine and change them. This makes the debugger more transparent. By
contrast, @kbd{M-:} does nothing special in the debugger; it shows you
-the variable values within the debugger.
+the variable values within the debugger. By default, this command
+suppresses the debugger during evaluation, so that an error in the
+evaluated expression won't add a new error on top of the existing one.
+Set the @code{debug-allow-recursive-debug} user option to a
+non-@code{nil} value to override this.
@item R
Like @kbd{e}, but also save the result of evaluation in the
diff --git a/doc/lispref/edebug.texi b/doc/lispref/edebug.texi
index eff9621628e..0fc5271d5ad 100644
--- a/doc/lispref/edebug.texi
+++ b/doc/lispref/edebug.texi
@@ -700,8 +700,12 @@ on this process.
@table @kbd
@item e @var{exp} @key{RET}
Evaluate expression @var{exp} in the context outside of Edebug
-(@code{edebug-eval-expression}). That is, Edebug tries to minimize its
-interference with the evaluation.
+(@code{edebug-eval-expression}). That is, Edebug tries to minimize
+its interference with the evaluation. By default, this command
+suppresses the debugger during evaluation, so that an error in the
+evaluated expression won't add a new error on top of the existing one.
+Set the @code{debug-allow-recursive-debug} user option to a
+non-@code{nil} value to override this.
@item M-: @var{exp} @key{RET}
Evaluate expression @var{exp} in the context of Edebug itself
diff --git a/etc/NEWS b/etc/NEWS
index 88b4e59e267..090d0b6dddc 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -686,6 +686,14 @@ script that was used in ancient South Asia. A new input method,
* Changes in Specialized Modes and Packages in Emacs 29.1
+** Debugging
+
+*** New user option 'debug-allow-recursive-debug'.
+This user option controls whether the 'e' (in a *Backtrace*
+buffer or while edebugging) and 'C-x C-e' (while edebugging) commands
+lead to a (further) backtrace. By default, this variable is nil,
+which is a change in behaviour from previous Emacs versions.
+
** Compile
+++
diff --git a/lisp/emacs-lisp/debug.el b/lisp/emacs-lisp/debug.el
index 46b0306d64f..91e9b0716d0 100644
--- a/lisp/emacs-lisp/debug.el
+++ b/lisp/emacs-lisp/debug.el
@@ -90,6 +90,11 @@ The value used here is passed to `quit-restore-window'."
:group 'debugger
:version "24.3")
+(defcustom debug-allow-recursive-debug nil
+ "If non-nil, erroring in debug and edebug won't recursively debug."
+ :type 'boolean
+ :version "29.1")
+
(defvar debugger-step-after-exit nil
"Non-nil means \"single-step\" after the debugger exits.")
@@ -534,7 +539,13 @@ The environment used is the one when entering the activation frame at point."
(error 0)))) ;; If on first line.
(base (debugger--backtrace-base)))
(debugger-env-macro
- (let ((val (backtrace-eval exp nframe base)))
+ (let ((val (if debug-allow-recursive-debug
+ (backtrace-eval exp nframe base)
+ (condition-case err
+ (backtrace-eval exp nframe base)
+ (error (format "%s: %s"
+ (get (car err) 'error-message)
+ (car (cdr err))))))))
(prog1
(debugger--print val t)
(let ((str (eval-expression-print-format val)))
diff --git a/lisp/emacs-lisp/edebug.el b/lisp/emacs-lisp/edebug.el
index 722283b88ff..85545f9f351 100644
--- a/lisp/emacs-lisp/edebug.el
+++ b/lisp/emacs-lisp/edebug.el
@@ -57,6 +57,7 @@
(require 'cl-lib)
(require 'seq)
(eval-when-compile (require 'pcase))
+(require 'debug)
;;; Options
@@ -3713,7 +3714,9 @@ Print result in minibuffer."
(interactive (list (read--expression "Eval: ")))
(princ
(edebug-outside-excursion
- (let ((result (edebug-eval expr)))
+ (let ((result (if debug-allow-recursive-debug
+ (edebug-eval expr)
+ (edebug-safe-eval expr))))
(values--store-value result)
(concat (edebug-safe-prin1-to-string result)
(eval-expression-print-format result))))))