[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH]: Re: Early backtrace.
From: |
Alan Mackenzie |
Subject: |
[PATCH]: Re: Early backtrace. |
Date: |
Sun, 30 Jan 2022 11:07:32 +0000 |
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).
- Early backtrace., Alan Mackenzie, 2022/01/10
- Re: Early backtrace., Stefan Monnier, 2022/01/10
- Re: Early backtrace., Alan Mackenzie, 2022/01/11
- Re: Early backtrace., Stefan Monnier, 2022/01/11
- [PATCH]: Re: Early backtrace.,
Alan Mackenzie <=
- Re: [PATCH]: Re: Early backtrace., Stefan Monnier, 2022/01/30
- Re: [PATCH]: Re: Early backtrace., Stefan Monnier, 2022/01/31
- Re: [PATCH]: Re: Early backtrace., Philipp Stephani, 2022/01/31
- Re: [PATCH]: Re: Early backtrace., Eli Zaretskii, 2022/01/31
- Re: [PATCH]: Re: Early backtrace., Alan Mackenzie, 2022/01/31
- Re: [PATCH]: Re: Early backtrace., Alan Mackenzie, 2022/01/31