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).
next prev parent 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
* 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 external index
https://git.savannah.gnu.org/cgit/emacs.git
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.