Subject: bug#61847: debug-early-backtrace only works some of the time.

From: Alan Mackenzie <[email-masked]>
Date: Mon, 27 Feb 2023 17:11:51 +0000

Hello, Emacs.

In the master branch:

Sometimes, instead of outputting a backtrace, debug-early throws an
error, like the second line of:

Error: cl-assertion-failed ((stringp typename))
Symbol's function definition is void: cl-defgeneric

..  To reproduce this failure, apply the following patch to src/eval.c,
then attempt a make bootstrap:

diff --git a/src/eval.c b/src/eval.c
index d42f7ffe894..8a88f5894b1 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -542,13 +542,13 @@ DEFUN ("function", Ffunction, Sfunction, 1, UNEVALLED, 0,
 	  && (EQ (QCdocumentation, XCAR (tmp))))
 	{ /* Handle the special (:documentation <form>) to build the docstring
 	     dynamically.  */
-	  Lisp_Object docstring = eval_sub (Fcar (XCDR (tmp)));
-	  if (SYMBOLP (docstring) && !NILP (docstring))
-	    /* Hack for OClosures: Allow the docstring to be a symbol
-             * (the OClosure's type).  */
-	    docstring = Fsymbol_name (docstring);
-	  CHECK_STRING (docstring);
-	  cdr = Fcons (XCAR (cdr), Fcons (docstring, XCDR (XCDR (cdr))));
+	  /* Lisp_Object docstring = eval_sub (Fcar (XCDR (tmp))); */
+	  /* if (SYMBOLP (docstring) && !NILP (docstring)) */
+	  /*   /\* Hack for OClosures: Allow the docstring to be a symbol */
+          /*    * (the OClosure's type).  *\/ */
+	  /*   docstring = Fsymbol_name (docstring); */
+	  /* CHECK_STRING (docstring); */
+	  /* cdr = Fcons (XCAR (cdr), Fcons (docstring, XCDR (XCDR (cdr)))); */
 	}
       if (NILP (Vinternal_make_interpreted_closure_function))
         return Fcons (Qclosure, Fcons (Vinternal_interpreter_environment, cdr));

..

The cause of the problem was patch

commit 08108a856a544a80d11b1e9e437fe6c45e25adec
Author: Stefan Monnier <[email-masked]>
Date:   Fri Apr 29 22:18:09 2022 -0400

    debug-early: Print bytecode in a more manageable way

    * lisp/emacs-lisp/debug-early.el (debug-early-backtrace):
    Escape newlines to and bytecodes to make backtraces slightly more
    readable.  Use `cl-prin1` when available.

, which made debug-early.el dependent on arbitrarily nested Lisp code, in
violation of its explicitly stated design goal to have _no_ dependence on
Lisp code.  Some of this Lisp simply fails to load.  It's not clear why
the patch was applied.

I propose fixing the bug by restoring the code to having no such
dependencies with the following patch:

diff --git a/lisp/emacs-lisp/debug-early.el b/lisp/emacs-lisp/debug-early.el
index 395498f2206..723269f3ea0 100644
--- a/lisp/emacs-lisp/debug-early.el
+++ b/lisp/emacs-lisp/debug-early.el
@@ -44,28 +44,21 @@ 'debug-early-backtrace
       (princ "\n")
       (let ((print-escape-newlines t)
             (print-escape-control-characters t)
-            (print-escape-nonascii t)
-            (prin1 (if (and (fboundp 'cl-prin1)
-                            ;; If we're being called while
-                            ;; bootstrapping, we won't be able to load
-                            ;; cl-print.
-                            (require 'cl-print nil t))
-                       #'cl-prin1
-                     #'prin1)))
+            (print-escape-nonascii t))
         (mapbacktrace
          #'(lambda (evald func args _flags)
              (let ((args args))
 	       (if evald
 	           (progn
 	             (princ "  ")
-	             (funcall prin1 func)
+	             (prin1 func)
 	             (princ "("))
 	         (progn
 	           (princ "  (")
 	           (setq args (cons func args))))
 	       (if args
 	           (while (progn
-	                    (funcall prin1 (car args))
+	                    (prin1 (car args))
 	                    (setq args (cdr args)))
 	             (princ " ")))
 	       (princ ")\n")))))))

..  Any objections to applying this patch?

-- 
Alan Mackenzie (Nuremberg, Germany).