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.bugs Subject: bug#67196: M-: uses a wrong value of debug-on-error when it is nil. Date: Sat, 25 Nov 2023 12:40:03 +0000 Message-ID: References: <83ttpbdm2f.fsf@gnu.org> <83il5qe00e.fsf@gnu.org> <83edgecce4.fsf@gnu.org> 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="17639"; mail-complaints-to="usenet@ciao.gmane.io" Cc: 67196@debbugs.gnu.org, acm@muc.de, monnier@iro.umontreal.ca To: Eli Zaretskii Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Sat Nov 25 13:41:14 2023 Return-path: Envelope-to: geb-bug-gnu-emacs@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 1r6ryD-0004RT-VS for geb-bug-gnu-emacs@m.gmane-mx.org; Sat, 25 Nov 2023 13:41:14 +0100 Original-Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1r6ry6-00008F-W0; Sat, 25 Nov 2023 07:41:07 -0500 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1r6ry1-000085-Ts for bug-gnu-emacs@gnu.org; Sat, 25 Nov 2023 07:41:03 -0500 Original-Received: from debbugs.gnu.org ([2001:470:142:5::43]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1r6rxx-0000KQ-BP for bug-gnu-emacs@gnu.org; Sat, 25 Nov 2023 07:41:00 -0500 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1r6ry2-0006PX-CB for bug-gnu-emacs@gnu.org; Sat, 25 Nov 2023 07:41:02 -0500 X-Loop: help-debbugs@gnu.org Resent-From: Alan Mackenzie Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sat, 25 Nov 2023 12:41:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 67196 X-GNU-PR-Package: emacs Original-Received: via spool by 67196-submit@debbugs.gnu.org id=B67196.170091602224570 (code B ref 67196); Sat, 25 Nov 2023 12:41:02 +0000 Original-Received: (at 67196) by debbugs.gnu.org; 25 Nov 2023 12:40:22 +0000 Original-Received: from localhost ([127.0.0.1]:38090 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1r6rxN-0006OB-Gn for submit@debbugs.gnu.org; Sat, 25 Nov 2023 07:40:22 -0500 Original-Received: from mail.muc.de ([193.149.48.3]:22151) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1r6rxH-0006Ns-Qj for 67196@debbugs.gnu.org; Sat, 25 Nov 2023 07:40:20 -0500 Original-Received: (qmail 63277 invoked by uid 3782); 25 Nov 2023 13:40:04 +0100 Original-Received: from acm.muc.de (pd953a2e3.dip0.t-ipconnect.de [217.83.162.227]) (using STARTTLS) by colin.muc.de (tmda-ofmipd) with ESMTP; Sat, 25 Nov 2023 13:40:04 +0100 Original-Received: (qmail 16230 invoked by uid 1000); 25 Nov 2023 12:40:03 -0000 Content-Disposition: inline In-Reply-To: <83edgecce4.fsf@gnu.org> X-Submission-Agent: TMDA/1.3.x (Ph3nix) X-Primary-Address: acm@muc.de X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Original-Sender: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Xref: news.gmane.io gmane.emacs.bugs:274969 Archived-At: Hello, Eli. On Sat, Nov 25, 2023 at 13:15:15 +0200, Eli Zaretskii wrote: > > Date: Sat, 25 Nov 2023 10:32:23 +0000 > > Cc: monnier@iro.umontreal.ca, 67196@debbugs.gnu.org > > From: Alan Mackenzie > > > How about not exposing the internal variable to Lisp at all? > > That's a very good idea. It would need little more than a new C function > > which would bind that variable then call eval. Maybe move > > eval-expression-debug-on-error into eval.c, too. > What I had in mind was a function exposed to Lisp that would set an > internal variable not exposed to Lisp. The would still require an unwind-protect somewhere. I've implemented sub-eval-expression in eval.c. debug-from--eval-expression is no longer visible from Lisp. Perhaps this is good enough. > > > > For what it's worth, I lost about 10 hours of time trying to debug > > > > a situation where I wasn't getting a backtrace, despite debug-on-error > > > > being t. The problem was that d-o-e wasn't t at all, it was nil. M-: > > > > had been lying. > > > You never described that situation, AFAICT. I think you should, so > > > that we could assess how grave the problem is, which is an important > > > part of deciding whether the solution you propose is useful. I don't > > > understand how could you NOT get a backtrace when debug-on-error is > > > non-nil. > > Sorry, I wasn't clear enough. During those 10 hours, I was under the > > impression that debug-on-error was t, because M-: debug-on-error said so. > > It actually was nil. That's why I submitted this bug report. > So maybe instead of changing how this stuff works we should improve > how debug-on-error's value is reported by M-: and other eval commands? Yes, but that might be complicated, and won't help the user trying to debug something which depends on debug-on-error, who is using M-: to try to test it. I still say the bug is trying to make debug-on-error do too much, more than it's capable of. > Note that (AFAIU) your change doesn't just solve the problem you > bumped into, it also changes the value of debug-on-error inside > eval-expression etc., when eval-expression-debug-on-error's value is > non-nil, but not t. I wonder what is the reason for that? I don't see that in my current version of the patch (below). To test this, I used the following: (defun foo () (interactive) (message "debug-on-error is %s" debug-on-error) (message "eval-expression-debug-on-error is %s" eval-expression-debug-on-error) (car 'foo)) , and called it with various settings of debug-on-error and eval-expression-debug-on-error. In particular, with (setq eval-expression-debug-on-error '(wrong-type-argument)) , I still see debug-on-error reported as nil. diff --git a/lisp/cus-start.el b/lisp/cus-start.el index 6d83aaf4d14..9d176c6c599 100644 --- a/lisp/cus-start.el +++ b/lisp/cus-start.el @@ -262,6 +262,13 @@ minibuffer-prompt-properties--setter :value (nil) (symbol :format "%v")) (const :tag "always" t))) + (eval-expression-debug-on-error debug + (choice (const :tag "off") + (repeat :menu-tag "When" + :value (nil) + (symbol :format "%v")) + (const :tag "always" t)) + "30.1") (debug-ignored-errors debug (repeat (choice symbol regexp))) (debug-on-quit debug boolean) (debug-on-signal debug boolean) diff --git a/lisp/simple.el b/lisp/simple.el index 02c68912dba..f4c9873ceed 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -1980,13 +1980,6 @@ eval-expression-print-length :type '(choice (const :tag "No Limit" nil) integer) :version "21.1") -(defcustom eval-expression-debug-on-error t - "If non-nil set `debug-on-error' to t in `eval-expression'. -If nil, don't change the value of `debug-on-error'." - :group 'lisp - :type 'boolean - :version "21.1") - (defcustom eval-expression-print-maximum-character 127 "The largest integer that will be displayed as a character. This affects printing by `eval-expression' (via @@ -2120,34 +2113,18 @@ eval-expression (cons (read--expression "Eval: ") (eval-expression-get-print-arguments current-prefix-arg))) - (let (result) - (if (null eval-expression-debug-on-error) - (setq result - (values--store-value - (eval (let ((lexical-binding t)) (macroexpand-all exp)) t))) - (let ((old-value (make-symbol "t")) new-value) - ;; Bind debug-on-error to something unique so that we can - ;; detect when evalled code changes it. - (let ((debug-on-error old-value)) - (setq result - (values--store-value - (eval (let ((lexical-binding t)) (macroexpand-all exp)) t))) - (setq new-value debug-on-error)) - ;; If evalled code has changed the value of debug-on-error, - ;; propagate that change to the global binding. - (unless (eq old-value new-value) - (setq debug-on-error new-value)))) - - (let ((print-length (unless no-truncate eval-expression-print-length)) - (print-level (unless no-truncate eval-expression-print-level)) - (eval-expression-print-maximum-character char-print-limit) - (deactivate-mark)) - (let ((out (if insert-value (current-buffer) t))) - (prog1 - (prin1 result out) - (let ((str (and char-print-limit - (eval-expression-print-format result)))) - (when str (princ str out)))))))) + (let* ((result (values--store-value + (sub-eval-expression (macroexpand-all exp)))) + (print-length (unless no-truncate eval-expression-print-length)) + (print-level (unless no-truncate eval-expression-print-level)) + (eval-expression-print-maximum-character char-print-limit) + (deactivate-mark) + (out (if insert-value (current-buffer) t))) + (prog1 + (prin1 result out) + (let ((str (and char-print-limit + (eval-expression-print-format result)))) + (when str (princ str out)))))) (defun edit-and-eval-command (prompt command) "Prompting with PROMPT, let user edit COMMAND and eval result. diff --git a/src/eval.c b/src/eval.c index 12e811ce264..eccabf3a091 100644 --- a/src/eval.c +++ b/src/eval.c @@ -2033,7 +2033,8 @@ maybe_call_debugger (Lisp_Object conditions, Lisp_Object sig, Lisp_Object data) /* Does user want to enter debugger for this kind of error? */ && (signal_quit_p (sig) ? debug_on_quit - : wants_debugger (Vdebug_on_error, conditions)) + : (wants_debugger (Vdebug_from__eval_expression, conditions) + || wants_debugger (Vdebug_on_error, conditions))) && ! skip_debugger (conditions, combined_data) /* See commentary on definition of `internal-when-entered-debugger'. */ @@ -2383,6 +2384,19 @@ DEFUN ("eval", Feval, Seval, 1, 2, 0, return unbind_to (count, eval_sub (form)); } +DEFUN ("sub-eval-expression", Fsub_eval_expression, Ssub_eval_expression, + 1, 1, 0, + doc: /* Evaluate FORM and return its value. +This function should be called only from `eval-expression'. +It evaluates with `lexical-binding' non-nil, and handles +`eval-expression-debug-on-error'. */) + (Lisp_Object form) +{ + specpdl_ref count = SPECPDL_INDEX (); + specbind (Qdebug_from__eval_expression, Veval_expression_debug_on_error); + return unbind_to (count, Feval (form, Qt)); +} + void grow_specpdl_allocation (void) { @@ -4299,6 +4313,29 @@ syms_of_eval (void) See also the variable `debug-on-quit' and `inhibit-debugger'. */); Vdebug_on_error = Qnil; + DEFSYM (Qeval_expression_debug_on_error, "eval-expression-debug-on-error"); + DEFVAR_LISP ("eval-expression-debug-on-error", + Veval_expression_debug_on_error, + doc: /* Non-nil means enter debugger on error on a call from `eval-expression'. +Does not apply to errors handled by `condition-case' or those +matched by `debug-ignored-errors'. +Like `debug-on-error', this variable's value can also be a list, +with the same meaning as for `debug-on-error'. + +A nil value for this variable will not prevent an entry to +the debugger caused by other variables such as `debug-on-error'. */); + Veval_expression_debug_on_error = Qt; + + DEFSYM (Qdebug_from__eval_expression, "debug-from--eval-expression"); + DEFVAR_LISP ("debug-from--eval-expression", Vdebug_from__eval_expression, + doc: /* Non-nil means enter debugger if an error is signaled. +This only applies in forms called by `eval-expression'. This variable +has the same semantics as `debug-on-error'. It is an internal variable +only. */); + Vdebug_from__eval_expression = Qnil; + /* debug-from--eval-expression should not be visible from Lisp. */ + Funintern (Qdebug_from__eval_expression, Qnil); + DEFVAR_LISP ("debug-ignored-errors", Vdebug_ignored_errors, doc: /* List of errors for which the debugger should not be called. Each element may be a condition-name or a regexp that matches error messages. @@ -4455,6 +4492,7 @@ syms_of_eval (void) defsubr (&Sautoload); defsubr (&Sautoload_do_load); defsubr (&Seval); + defsubr (&Ssub_eval_expression); defsubr (&Sapply); defsubr (&Sfuncall); defsubr (&Sfunc_arity); -- Alan Mackenzie (Nuremberg, Germany).