unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
From: Alan Mackenzie <acm@muc.de>
To: Stefan Monnier <monnier@iro.umontreal.ca>
Cc: emacs-devel@gnu.org
Subject: [PATCH]: Re: Early backtrace.
Date: Sun, 30 Jan 2022 11:07:32 +0000	[thread overview]
Message-ID: <YfZxdNv3fsD6sSq0@ACM> (raw)
In-Reply-To: <jwva6g21gfw.fsf-monnier+emacs@gnu.org>

Hello, everybody.

On Tue, Jan 11, 2022 at 09:47:34 -0500, Stefan Monnier wrote:
> >> I have a similar hack here for the same reason ;-)
> >> So a +1 from me (tho I'd recommend using the `debugger-` namespace
> >> rather than `early-`).

> > Thanks!  Maybe `debug-early' and `backtrace-early' would do for the two
> > functions?  There isn't really a debugger- prefix that early in the
> > bootstrap.

> Namespace prefixes don't need to be created before we use them.
> The point is just that `debugger-` is already used by definitions (in
> `debug.el`) so we can reuse that space instead of messing up pristine
> real estate.

OK, I've called it debug-early.

> > No, inside signal_or_quit, Vdebugger gets bound to Qdebug, so as to
> > bypass the setting made in ERT.  Also it is filtered out by checking for
> > not being in dump or bootstrap.  Instead, we should check Ffboundp
> > (Qdebug) || Ffboundp (Qdebug_early).  Not difficult to do.

> Oh, god, I didn't know (or forgot) about that horror.
> We should throw it out: your code should make it obsolete.
> E.g. we can take your new code as the default value of `debugger` and
> only replace it with `#'debugger` when an interactive frame
> is available.

debug-early.el installs itself as the debugger when it loads.  I've made
debug-early the dump routine used in batch mode.

I now have a patch ready.  It permits a Lisp backtrace to be created
early in the bootstrapping process.

It also fixes a bug in signal_or_quit (eval.c) where previously there
was:

      specbind (Vdebugger, Qdebug);

, which had the effect of binding the contents of Vdebugger (namely
Qdebug) to itself.  Correct would have been:

      specbind (Qdebugger, Qdebug);

, binding the symbol Qdebugger to Qdebug.

The patch loads lisp/emacs-lisp/debug-early.el as the first loaded by
loadup.el, and creates debug-early.el.

Are there any objections to me committing this to master?



diff --git a/lisp/loadup.el b/lisp/loadup.el
index 1be73a2090..81172c584d 100644
--- a/lisp/loadup.el
+++ b/lisp/loadup.el
@@ -128,6 +128,7 @@
 (set-buffer "*scratch*")
 (setq buffer-undo-list t)
 
+(load "emacs-lisp/debug-early")
 (load "emacs-lisp/byte-run")
 (load "emacs-lisp/backquote")
 (load "subr")
diff --git a/src/eval.c b/src/eval.c
index 6a8c759c1d..034f8bf6e4 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -1893,18 +1893,19 @@ signal_or_quit (Lisp_Object error_symbol, Lisp_Object data, bool keyboard_quit)
     }
 
   /* 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.  Don't try to call the debugger while dumping or
-     bootstrapping, it wouldn't work anyway.  */
+     with debugging.  Make sure to use `debug-early' 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 && backtrace_on_error_noninteractive
-      && !will_dump_p () && !will_bootstrap_p ()
-      && NILP (Vinhibit_debugger))
+      && NILP (Vinhibit_debugger)
+      && !NILP (Ffboundp (Qdebug_early)))
     {
+      max_ensure_room (&max_lisp_eval_depth, lisp_eval_depth, 100);
+      max_ensure_room (&max_specpdl_size, SPECPDL_INDEX (), 200);
       ptrdiff_t count = SPECPDL_INDEX ();
-      specbind (Vdebugger, Qdebug);
+      specbind (Qdebugger, Qdebug_early);
       call_debugger (list2 (Qerror, Fcons (error_symbol, data)));
       unbind_to (count, Qnil);
     }
@@ -4421,6 +4422,7 @@ syms_of_eval (void)
   DEFSYM (Qclosure, "closure");
   DEFSYM (QCdocumentation, ":documentation");
   DEFSYM (Qdebug, "debug");
+  DEFSYM (Qdebug_early, "debug-early");
 
   DEFVAR_LISP ("inhibit-debugger", Vinhibit_debugger,
 	       doc: /* Non-nil means never enter the debugger.
@@ -4467,6 +4469,7 @@ syms_of_eval (void)
 	       doc: /* Non-nil means display call stack frames as lists. */);
   debugger_stack_frame_as_list = 0;
 
+  DEFSYM (Qdebugger, "debugger");
   DEFVAR_LISP ("debugger", Vdebugger,
 	       doc: /* Function to call to invoke debugger.
 If due to frame exit, args are `exit' and the value being returned;


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;; debug-early.el --- Dump a Lisp backtrace without frills  -*- lexical-binding: t; -*-

;; Copyright (C) 2022 Free Software Foundation, Inc.

;; Author: Alan Mackenzie <acm@muc.de>
;; Maintainer: emacs-devel@gnu.org
;; Keywords: internal, backtrace, bootstrap.
;; Package: emacs

;; This file is part of GNU Emacs.

;; GNU Emacs is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.

;; GNU Emacs is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;; GNU General Public License for more details.

;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.

;;; Commentary:

;; This file dumps a backtrace on stderr when an error is thrown.
;; It has no dependencies on any Lisp libraries and is thus suitable
;; for generating backtraces in the early parts of bootstrapping.  It
;; is also good for generating backtraces in batch mode in general.

(defalias 'debug-early-backtrace
  #'(lambda ()
  "Print a trace of Lisp function calls currently active.
The output stream used is the value of `standard-output'.

This is a simplified version of the standard `backtrace'
function, intended for use in debugging the early parts
of the build process."
  (princ "\n")
  (mapbacktrace
   #'(lambda (evald func args _flags)
       (let ((args args))
	 (if evald
	     (progn
	       (princ "  ")
	       (prin1 func)
	       (princ " (")
	       (while args
		 (prin1 (car args))
		 (setq args (cdr args))
		 (if args
		     (princ " ")))
	       (princ ")\n"))
	   (while args
	     (princ "  ")
	     (prin1 (car args))
	     (princ "\n")
	     (setq args (cdr args)))))))))

(defalias 'debug-early
  #'(lambda (&rest args)
  "Print a trace of Lisp function calls currently active.
The output stream used is the value of `standard-output'.

There should be two ARGS, the symbol `error' and a cons of
the error symbol and its data.

This is a simplified version of `debug', intended for use
in debugging the early parts of the build process."
  (princ "\nError: ")
  (prin1 (car (car (cdr args))))	; The error symbol.
  (princ " ")
  (prin1 (cdr (car (cdr args))))	; The error data.
  (debug-early-backtrace)))

(setq debugger #'debug-early)

;;; debug-early.el ends here.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

>         Stefan

-- 
Alan Mackenzie (Nuremberg, Germany).



  reply	other threads:[~2022-01-30 11:07 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-01-10 20:34 Early backtrace Alan Mackenzie
2022-01-10 21:54 ` Stefan Monnier
2022-01-11 11:36   ` Alan Mackenzie
2022-01-11 14:47     ` Stefan Monnier
2022-01-30 11:07       ` Alan Mackenzie [this message]
2022-01-30 16:31         ` [PATCH]: " Stefan Monnier
2022-01-31 14:04           ` Stefan Monnier
2022-02-01 19:14           ` Alan Mackenzie
2022-02-02  3:36             ` Stefan Monnier
2022-02-02 20:38               ` Alan Mackenzie
2022-02-02 20:59                 ` Stefan Monnier
2022-02-03  8:38                   ` Eli Zaretskii
2022-02-03 21:35                     ` Alan Mackenzie
2022-02-04  7:24                       ` Eli Zaretskii
2022-02-04 21:01                         ` Alan Mackenzie
2022-02-05  7:12                           ` Eli Zaretskii
2022-02-05 10:48                             ` Alan Mackenzie
2022-02-04 13:31                     ` Stefan Monnier
2022-02-04 14:02                       ` Eli Zaretskii
2022-01-31  9:30         ` Philipp Stephani
2022-01-31 12:42           ` Eli Zaretskii
2022-01-31 16:54             ` Alan Mackenzie
2022-01-31 17:24               ` Alan Mackenzie

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=YfZxdNv3fsD6sSq0@ACM \
    --to=acm@muc.de \
    --cc=emacs-devel@gnu.org \
    --cc=monnier@iro.umontreal.ca \
    /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).