From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Alan Mackenzie Newsgroups: gmane.emacs.devel Subject: [PATCH]: Re: Early backtrace. Date: Sun, 30 Jan 2022 11:07:32 +0000 Message-ID: References: Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="25535"; mail-complaints-to="usenet@ciao.gmane.io" Cc: emacs-devel@gnu.org To: Stefan Monnier Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Sun Jan 30 12:08:49 2022 Return-path: Envelope-to: ged-emacs-devel@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1nE84f-0006Sv-CO for ged-emacs-devel@m.gmane-mx.org; Sun, 30 Jan 2022 12:08:49 +0100 Original-Received: from localhost ([::1]:59166 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1nE84e-0002Ei-0O for ged-emacs-devel@m.gmane-mx.org; Sun, 30 Jan 2022 06:08:48 -0500 Original-Received: from eggs.gnu.org ([209.51.188.92]:34732) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nE83X-0000te-VH for emacs-devel@gnu.org; Sun, 30 Jan 2022 06:07:40 -0500 Original-Received: from colin.muc.de ([193.149.48.1]:39582 helo=mail.muc.de) by eggs.gnu.org with smtp (Exim 4.90_1) (envelope-from ) id 1nE83U-0000Qt-Rq for emacs-devel@gnu.org; Sun, 30 Jan 2022 06:07:39 -0500 Original-Received: (qmail 89123 invoked by uid 3782); 30 Jan 2022 11:07:32 -0000 Original-Received: from acm.muc.de (p2e5d54eb.dip0.t-ipconnect.de [46.93.84.235]) (using STARTTLS) by colin.muc.de (tmda-ofmipd) with ESMTP; Sun, 30 Jan 2022 12:07:32 +0100 Original-Received: (qmail 25077 invoked by uid 1000); 30 Jan 2022 11:07:32 -0000 Content-Disposition: inline In-Reply-To: X-Submission-Agent: TMDA/1.3.x (Ph3nix) X-Primary-Address: acm@muc.de Received-SPF: pass client-ip=193.149.48.1; envelope-from=acm@muc.de; helo=mail.muc.de X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Original-Sender: "Emacs-devel" Xref: news.gmane.io gmane.emacs.devel:285601 Archived-At: 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 ;; 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 . ;;; 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).