Subject: [patch] Backtrace printing in non-interactive mode doesn't use cl-prin1 etc.

From: Paul Pogonyshev <[email-masked]>
Date: Sat, 4 Jan 2020 23:01:53 +0100

tags

Backtrace printing in batch mode ignores all customizations, at least:
- all `cl-print-object' overrides (`debugger-print-function');
- `print-level', `print-length' and friends;
- `debugger-batch-max-lines'.

The reason is this commit:

7228488effa78dcb75284cb6d247b24804e0e7f5
Author:     Stefan Monnier <[email-masked]>
AuthorDate: 2018-04-02 00:23:20 -0400
[...]

* lisp/emacs-lisp/debug.el (debug): Don't hang upon error in initial-frame.

[...]
+   ((and (eq t (framep (selected-frame)))
+         (equal "initial_terminal" (terminal-name)))
+    ;; We're in the initial-frame (where `message' just outputs to stdout) so
+    ;; there's no tty or GUI frame to display the backtrace and interact with
+    ;; it: just dump a backtrace to stdout.
+    ;; This happens for example while handling an error in code from
+    ;; early-init.el with --debug-init.
+    (message "Error: %S" args)
[...]

The commit added a "failsafe" mode for (quoting) "initial-frame (where
`message' just outputs to stdout) so there's no tty or GUI frame".
This failsafe mode is also erroneously triggered in batch mode. It was
never meant for it: you can see a couple of uses of `noninteractive'
in the next `cond' branch, but execution now never gets to it.

Patch attached:
- don't use this "failsafe" mode when running non-interactively;
- repair for the latest changes in backtrace generation (apparently,
before the buffer was not read-only);
- repair adjustment for `debugger-batch-max-lines' which didn't make
any sense and didn't achieve what it claimed in the comment.

Paul
From 180f4a4f771696512af31ded93057713a5507147 Mon Sep 17 00:00:00 2001
From: Paul Pogonyshev <[email-masked]>
Date: Sat, 4 Jan 2020 22:47:24 +0100
Subject: [PATCH] Don't apply the special case to non-interactive mode in
 `debug'

---
 lisp/emacs-lisp/debug.el | 25 +++++++++++++------------
 1 file changed, 13 insertions(+), 12 deletions(-)

diff --git a/lisp/emacs-lisp/debug.el b/lisp/emacs-lisp/debug.el
index 3df0ba4a65..b6c58b8c7b 100644
--- a/lisp/emacs-lisp/debug.el
+++ b/lisp/emacs-lisp/debug.el
@@ -172,7 +172,8 @@ debug
    (inhibit-redisplay
     ;; Don't really try to enter debugger within an eval from redisplay.
     debugger-value)
-   ((and (eq t (framep (selected-frame)))
+   ((and (not noninteractive)
+         (eq t (framep (selected-frame)))
          (equal "initial_terminal" (terminal-name)))
     ;; We're in the initial-frame (where `message' just outputs to stdout) so
     ;; there's no tty or GUI frame to display the backtrace and interact with
@@ -246,17 +247,17 @@ debug
 	        (when noninteractive
 		  ;; If the backtrace is long, save the beginning
 		  ;; and the end, but discard the middle.
-		  (when (> (count-lines (point-min) (point-max))
-			   debugger-batch-max-lines)
-		    (goto-char (point-min))
-		    (forward-line (/ 2 debugger-batch-max-lines))
-		    (let ((middlestart (point)))
-		      (goto-char (point-max))
-		      (forward-line (- (/ 2 debugger-batch-max-lines)
-				       debugger-batch-max-lines))
-		      (delete-region middlestart (point)))
-		    (insert "...\n"))
-		  (goto-char (point-min))
+                  (let ((inhibit-read-only t))
+		    (when (> (count-lines (point-min) (point-max))
+			     debugger-batch-max-lines)
+		      (goto-char (point-min))
+		      (forward-line (/ debugger-batch-max-lines 4))
+		      (let ((middlestart (point)))
+		        (goto-char (point-max))
+		        (forward-line (- (/ 2 debugger-batch-max-lines)
+				         debugger-batch-max-lines))
+		        (delete-region middlestart (point)))
+		      (insert "...\n")))
 		  (message "%s" (buffer-string))
 		  (kill-emacs -1)))
 	      (pop-to-buffer
-- 
2.20.1