unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
From: Philipp Stephani <p.stephani2@gmail.com>
To: 44942@debbugs.gnu.org
Subject: bug#44942: 28.0.50; Emacs should print a backtrace on uncaught errors in batch mode
Date: Sun, 29 Nov 2020 16:27:04 +0100	[thread overview]
Message-ID: <CAArVCkSWs6_8FDPxRxPONNQYbnL6etrHS=fhhv0=j9gXJN0=6A@mail.gmail.com> (raw)
In-Reply-To: <wvr47dq4jv72.fsf@gmail.com>

[-- Attachment #1: Type: text/plain, Size: 756 bytes --]

Am So., 29. Nov. 2020 um 11:48 Uhr schrieb Philipp Stephani
<p.stephani2@gmail.com>:
>
>
> $ emacs -Q -batch -eval '(progn (defun foo () (error "Boo")) (foo))'
> Boo
>
> Emacs should print a backtrace here to make it possible to debug such
> errors.  It's possible to force Emacs to print a backtrace by binding
> `debug-on-error', however, that is incorrect because it changes the
> meaning of `with-demoted-errors' and `condition-case-unless-debug',
> causing code that would normally work to fail with an error.  Instead,
> `signal' should print a backtrace if in batch mode and if it jumps to
> the top-level error handler.  It looks like this logic could be
> special-cased in signal_or_quit, similar to the debugger logic.
>


I've attached a patch.

[-- Attachment #2: 0001-Print-a-backtrace-on-unhandled-errors-in-batch-mode-.patch --]
[-- Type: text/x-patch, Size: 4861 bytes --]

From 6441ca2ca9ed0233cdf474cc64a860a3cff51222 Mon Sep 17 00:00:00 2001
From: Philipp Stephani <phst@google.com>
Date: Sun, 29 Nov 2020 14:24:57 +0100
Subject: [PATCH] Print a backtrace on unhandled errors in batch mode
 (Bug#44942).

* src/eval.c (signal_or_quit): Print a backtrace in batch mode if no
error handler was found.

* test/src/eval-tests.el (eval-tests/backtrace-in-batch-mode)
(eval-tests/backtrace-in-batch-mode/demoted-errors): New unit tests.

* etc/NEWS: Document change.
---
 etc/NEWS               |  3 +++
 src/eval.c             | 15 ++++++++++++++-
 test/src/eval-tests.el | 33 +++++++++++++++++++++++++++++++++
 3 files changed, 50 insertions(+), 1 deletion(-)

diff --git a/etc/NEWS b/etc/NEWS
index 2fb33e342e..baae624f27 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -192,6 +192,9 @@ have been replaced with "chat.freenode.net" throughout Emacs.
 These functions return the connection local value of the respective
 variables.  This can be used for remote hosts.
 
+** Emacs now prints a backtrace when signaling an error in batch mode.  This
+makes debugging Emacs Lisp scripts run in batch mode easier.
+
 \f
 * Editing Changes in Emacs 28.1
 
diff --git a/src/eval.c b/src/eval.c
index d9a424b57a..18df484aac 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -1709,6 +1709,7 @@ signal_or_quit (Lisp_Object error_symbol, Lisp_Object data, bool keyboard_quit)
 	break;
     }
 
+  bool debugger_called = false;
   if (/* Don't run the debugger for a memory-full error.
 	 (There is no room in memory to do that!)  */
       !NILP (error_symbol)
@@ -1722,7 +1723,7 @@ signal_or_quit (Lisp_Object error_symbol, Lisp_Object data, bool keyboard_quit)
 	     if requested".  */
 	  || EQ (h->tag_or_ch, Qerror)))
     {
-      bool debugger_called
+      debugger_called
 	= maybe_call_debugger (conditions, error_symbol, data);
       /* We can't return values to code which signaled an error, but we
 	 can continue code which has signaled a quit.  */
@@ -1730,6 +1731,18 @@ signal_or_quit (Lisp_Object error_symbol, Lisp_Object data, bool keyboard_quit)
 	return Qnil;
     }
 
+  /* If we're in batch mode, print a backtrace unconditionally to help with
+     debugging.  Make sure to use `debug' unconditionally to not interfere with
+     ERT or other packages that install custom debuggers.  */
+  if (!debugger_called && !NILP (error_symbol)
+      && (NILP (clause) || EQ (h->tag_or_ch, Qerror)) && noninteractive)
+    {
+      ptrdiff_t count = SPECPDL_INDEX ();
+      specbind (Vdebugger, Qdebug);
+      call_debugger (list2 (Qerror, Fcons (error_symbol, data)));
+      unbind_to (count, Qnil);
+    }
+
   if (!NILP (clause))
     {
       Lisp_Object unwind_data
diff --git a/test/src/eval-tests.el b/test/src/eval-tests.el
index 074f5be1ef..4125573dc6 100644
--- a/test/src/eval-tests.el
+++ b/test/src/eval-tests.el
@@ -27,6 +27,7 @@
 
 (require 'ert)
 (eval-when-compile (require 'cl-lib))
+(require 'subr-x)
 
 (ert-deftest eval-tests--bug24673 ()
   "Check that Bug#24673 has been fixed."
@@ -176,4 +177,36 @@ eval-tests-19790-backquote-comma-dot-substitution
 expressions works for identifiers starting with period."
   (should (equal (let ((.x 'identity)) (eval `(,.x 'ok))) 'ok)))
 
+(ert-deftest eval-tests/backtrace-in-batch-mode ()
+  (let ((emacs (expand-file-name invocation-name invocation-directory)))
+    (skip-unless (file-executable-p emacs))
+    (with-temp-buffer
+      (let ((status (call-process emacs nil t nil
+                                  "--quick" "--batch"
+                                  (concat "--eval="
+                                          (prin1-to-string
+                                           '(progn
+                                              (defun foo () (error "Boo"))
+                                              (foo)))))))
+        (should (natnump status))
+        (should-not (eql status 0)))
+      (goto-char (point-min))
+      (ert-info ((concat "Process output:\n" (buffer-string)))
+        (search-forward "  foo()")
+        (search-forward "  normal-top-level()")))))
+
+(ert-deftest eval-tests/backtrace-in-batch-mode/demoted-errors ()
+  (let ((emacs (expand-file-name invocation-name invocation-directory)))
+    (skip-unless (file-executable-p emacs))
+    (with-temp-buffer
+      (should (eql  0 (call-process emacs nil t nil
+                                    "--quick" "--batch"
+                                    (concat "--eval="
+                                            (prin1-to-string
+                                             '(with-demoted-errors "Error: %S"
+                                                (error "Boo")))))))
+      (goto-char (point-min))
+      (should (equal (string-trim (buffer-string))
+                     "Error: (error \"Boo\")")))))
+
 ;;; eval-tests.el ends here
-- 
2.29.2.454.gaff20da3a2-goog


  reply	other threads:[~2020-11-29 15:27 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-11-29 10:47 bug#44942: 28.0.50; Emacs should print a backtrace on uncaught errors in batch mode Philipp Stephani
2020-11-29 15:27 ` Philipp Stephani [this message]
2020-12-06 16:50   ` Philipp Stephani
2020-12-06 16:59     ` Eli Zaretskii
2020-12-07 10:29       ` Philipp Stephani
2020-12-07 10:42         ` Eli Zaretskii
2020-12-07 11:07           ` Philipp Stephani
2020-12-07 15:45             ` Eli Zaretskii
2020-12-07 15:07 ` Mattias Engdegård
2020-12-07 15:29   ` Philipp Stephani

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CAArVCkSWs6_8FDPxRxPONNQYbnL6etrHS=fhhv0=j9gXJN0=6A@mail.gmail.com' \
    --to=p.stephani2@gmail.com \
    --cc=44942@debbugs.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).