GNU bug report logs - #79403
30.1; M-x gdb startup problem with (eq gdb-debuginfod-enable-setting 'ask)

Previous Next

Package: emacs;

Reported by: Gustav Hållberg <gustav <at> gmail.com>

Date: Sun, 7 Sep 2025 15:18:01 UTC

Severity: normal

Found in version 30.1

To reply to this bug, email your comments to 79403 AT debbugs.gnu.org.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to bug-gnu-emacs <at> gnu.org:
bug#79403; Package emacs. (Sun, 07 Sep 2025 15:18:02 GMT) Full text and rfc822 format available.

Acknowledgement sent to Gustav Hållberg <gustav <at> gmail.com>:
New bug report received and forwarded. Copy sent to bug-gnu-emacs <at> gnu.org. (Sun, 07 Sep 2025 15:18:02 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Gustav Hållberg <gustav <at> gmail.com>
To: bug-gnu-emacs <at> gnu.org
Subject: 30.1;
 M-x gdb startup problem with (eq gdb-debuginfod-enable-setting 'ask)
Date: Sun, 7 Sep 2025 17:16:41 +0200
[Message part 1 (text/plain, inline)]
If gdb-debuginfod-enable-setting is set to 'ask, gdb-init-1 may be called
recursively, causing gdb-token-number (and other variables) to be reset in
the middle of startup.

This causes an "gdb-handle-reply: Wrong type argument: gdb-handler, nil"
error message and other "strange" behavior.

It triggers every time for me when attaching gdb to a running process:
"emacs -nw -q" and M-x gdb, "gdb -i=mi -p <some-pid>". I only tested it
with emacs 30.1 but the code seems to be the same at origin/master.

If you insert (when (> gdb-token-number 0) (edebug)) in the begining of
(gdb-init-1) you'll see what happens. Partial call trace:

  gdb-init-1()
   :
  gdb-update()
   :
  gdb-stopped(...)
   :
  gud-filter(...)
  read-from-minibuffer(...)
  y-or-n-p("Enable querying debuginfod servers for this session?")
   :
  gdb-init-1()
   :
  gdb-update()
  gdb("gdb -i=mi -p ...")

I don't know what the right fix is, but it doesn't seem right to wait for
user input in the middle of gdb-init-1.
[Message part 2 (text/html, inline)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#79403; Package emacs. (Sat, 13 Sep 2025 09:38:01 GMT) Full text and rfc822 format available.

Message #8 received at 79403 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Gustav Hållberg <gustav <at> gmail.com>
Cc: 79403 <at> debbugs.gnu.org
Subject: Re: bug#79403: 30.1;
 M-x gdb startup problem with (eq gdb-debuginfod-enable-setting 'ask)
Date: Sat, 13 Sep 2025 12:37:29 +0300
> From: Gustav Hållberg <gustav <at> gmail.com>
> Date: Sun, 7 Sep 2025 17:16:41 +0200
> 
> If gdb-debuginfod-enable-setting is set to 'ask, gdb-init-1 may be called recursively, causing
> gdb-token-number (and other variables) to be reset in the middle of startup.
> 
> This causes an "gdb-handle-reply: Wrong type argument: gdb-handler, nil" error message and other
> "strange" behavior.
> 
> It triggers every time for me when attaching gdb to a running process: "emacs -nw -q" and M-x gdb, "gdb -
> i=mi -p <some-pid>". I only tested it with emacs 30.1 but the code seems to be the same at origin/master.
> 
> If you insert (when (> gdb-token-number 0) (edebug)) in the begining of (gdb-init-1) you'll see what
> happens. Partial call trace:
> 
>   gdb-init-1()
>    :
>   gdb-update()
>    :
>   gdb-stopped(...)
>    :
>   gud-filter(...)
>   read-from-minibuffer(...)
>   y-or-n-p("Enable querying debuginfod servers for this session?")
>    :
>   gdb-init-1()
>    :
>   gdb-update()
>   gdb("gdb -i=mi -p ...")
> 
> I don't know what the right fix is, but it doesn't seem right to wait for user input in the middle of gdb-init-1.

Thanks.  Does the patch below give good results?

diff --git a/lisp/progmodes/gdb-mi.el b/lisp/progmodes/gdb-mi.el
index 74dff32..ebaff4a2 100644
--- a/lisp/progmodes/gdb-mi.el
+++ b/lisp/progmodes/gdb-mi.el
@@ -1108,7 +1108,9 @@ gdb-init-1
   ;; trigger questions about debuginfod queries.
   (if (eq gdb-debuginfod-enable 'ask)
       (setq gdb-debuginfod-enable
-            (y-or-n-p "Enable querying debuginfod servers for this session?")))
+            (let ((gud-filter-defer-flag t))
+              (y-or-n-p
+               "Enable querying debuginfod servers for this session?"))))
   (gdb-input (format "-gdb-set debuginfod enabled %s"
                      (if gdb-debuginfod-enable "on" "off"))
              'gdb-debuginfod-message)




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#79403; Package emacs. (Sat, 13 Sep 2025 10:27:02 GMT) Full text and rfc822 format available.

Message #11 received at 79403 <at> debbugs.gnu.org (full text, mbox):

From: Gustav Hållberg <gustav <at> gmail.com>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: 79403 <at> debbugs.gnu.org
Subject: Re: bug#79403: 30.1; M-x gdb startup problem with (eq
 gdb-debuginfod-enable-setting 'ask)
Date: Sat, 13 Sep 2025 12:25:52 +0200
[Message part 1 (text/plain, inline)]
>
> Thanks.  Does the patch below give good results?
>

Yes but gud-filter-defer-flag seems to be a global so if you have several
gdb sessions going they all get confused while waiting for the y-or-no-p.

To test I did:
1. M-x gdb, start debugging process A, stop at breakpoint
2. M-x gdb, attach to process B, waiting at y-or-n-p
3. Type "step" in A's gdb window
4. Answer "y" to the y-or-n-p for B

This sent output from A's gdb to B's gdb buffer!

It seems gud-filter-defer-flag and gud-filter-pending-text should be
buffer-local (or process properties?) to avoid this.
But I don't know this code at all so...

That said, your patch is definitely a big improvement and the above error
case is a bit contrived :)


> diff --git a/lisp/progmodes/gdb-mi.el b/lisp/progmodes/gdb-mi.el
> index 74dff32..ebaff4a2 100644
> --- a/lisp/progmodes/gdb-mi.el
> +++ b/lisp/progmodes/gdb-mi.el
> @@ -1108,7 +1108,9 @@ gdb-init-1
>    ;; trigger questions about debuginfod queries.
>    (if (eq gdb-debuginfod-enable 'ask)
>        (setq gdb-debuginfod-enable
> -            (y-or-n-p "Enable querying debuginfod servers for this
> session?")))
> +            (let ((gud-filter-defer-flag t))
> +              (y-or-n-p
> +               "Enable querying debuginfod servers for this session?"))))
>    (gdb-input (format "-gdb-set debuginfod enabled %s"
>                       (if gdb-debuginfod-enable "on" "off"))
>               'gdb-debuginfod-message)
>
[Message part 2 (text/html, inline)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#79403; Package emacs. (Sat, 13 Sep 2025 14:08:02 GMT) Full text and rfc822 format available.

Message #14 received at 79403 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Gustav Hållberg <gustav <at> gmail.com>
Cc: 79403 <at> debbugs.gnu.org
Subject: Re: bug#79403: 30.1; M-x gdb startup problem with (eq
 gdb-debuginfod-enable-setting 'ask)
Date: Sat, 13 Sep 2025 17:07:28 +0300
> From: Gustav Hållberg <gustav <at> gmail.com>
> Date: Sat, 13 Sep 2025 12:25:52 +0200
> Cc: 79403 <at> debbugs.gnu.org
> 
>  Thanks.  Does the patch below give good results?
> 
> Yes but gud-filter-defer-flag seems to be a global so if you have several gdb sessions going they all get
> confused while waiting for the y-or-no-p.
> 
> To test I did:
> 1. M-x gdb, start debugging process A, stop at breakpoint
> 2. M-x gdb, attach to process B, waiting at y-or-n-p
> 3. Type "step" in A's gdb window
> 4. Answer "y" to the y-or-n-p for B
> 
> This sent output from A's gdb to B's gdb buffer!
> 
> It seems gud-filter-defer-flag and gud-filter-pending-text should be buffer-local (or process properties?) to
> avoid this.
> But I don't know this code at all so...
> 
> That said, your patch is definitely a big improvement and the above error case is a bit contrived :)

Thanks, how about the patch below?

diff --git a/lisp/progmodes/gdb-mi.el b/lisp/progmodes/gdb-mi.el
index 74dff32..ebaff4a2 100644
--- a/lisp/progmodes/gdb-mi.el
+++ b/lisp/progmodes/gdb-mi.el
@@ -1108,7 +1108,9 @@ gdb-init-1
   ;; trigger questions about debuginfod queries.
   (if (eq gdb-debuginfod-enable 'ask)
       (setq gdb-debuginfod-enable
-            (y-or-n-p "Enable querying debuginfod servers for this session?")))
+            (let ((gud-filter-defer-flag t))
+              (y-or-n-p
+               "Enable querying debuginfod servers for this session?"))))
   (gdb-input (format "-gdb-set debuginfod enabled %s"
                      (if gdb-debuginfod-enable "on" "off"))
              'gdb-debuginfod-message)
diff --git a/lisp/progmodes/gud.el b/lisp/progmodes/gud.el
index 5980bc2..1d43028 100644
--- a/lisp/progmodes/gud.el
+++ b/lisp/progmodes/gud.el
@@ -793,6 +793,10 @@ gdb-first-prompt
 (defvar gud-filter-pending-text nil
   "Non-nil means this is text that has been saved for later in `gud-filter'.")
 
+(defvar gud-filter-defer-flag nil
+  "Non-nil means don't process anything from the debugger right now.
+It is saved for when this flag is not set.")
+
 ;; One of the nice features of GDB is its impressive support for
 ;; context-sensitive command completion.  We preserve that feature
 ;; in the GUD buffer by using a GDB command designed just for Emacs.
@@ -2829,6 +2833,11 @@ gud-common-init
   (if find-file (setq-local gud-find-file find-file))
   (setq gud-last-last-frame nil)
 
+  ;; We need these to be local to the process's buffer so that we could
+  ;; defer processing output for each debugging session separately.
+  (make-local-variable 'gud-filter-defer-flag)
+  (make-local-variable 'gud-filter-pending-text)
+
   (set-process-filter (get-buffer-process (current-buffer)) #'gud-filter)
   (set-process-sentinel (get-buffer-process (current-buffer)) #'gud-sentinel)
   (gud-set-buffer))
@@ -2837,34 +2846,32 @@ gud-set-buffer
   (when (derived-mode-p 'gud-mode)
     (setq gud-comint-buffer (current-buffer))))
 
-(defvar gud-filter-defer-flag nil
-  "Non-nil means don't process anything from the debugger right now.
-It is saved for when this flag is not set.")
-
 ;; These functions are responsible for inserting output from your debugger
 ;; into the buffer.  The hard work is done by the method that is
 ;; the value of gud-marker-filter.
 
 (defun gud-filter (proc string)
   ;; Here's where the actual buffer insertion is done
-  (let (output process-window)
-    (if (buffer-name (process-buffer proc))
-	(if gud-filter-defer-flag
-	    ;; If we can't process any text now,
-	    ;; save it for later.
-	    (setq gud-filter-pending-text
-		  (concat (or gud-filter-pending-text "") string))
-
-	  ;; If we have to ask a question during the processing,
-	  ;; defer any additional text that comes from the debugger
-	  ;; during that time.
-	  (let ((gud-filter-defer-flag t))
-	    ;; Process now any text we previously saved up.
-	    (if gud-filter-pending-text
-		(setq string (concat gud-filter-pending-text string)
-		      gud-filter-pending-text nil))
+  (let ((proc-buf (process-buffer proc))
+        (cbuf (current-buffer))
+        output process-window)
+    (if (buffer-name proc-buf)
+        (with-current-buffer proc-buf
+	  (if gud-filter-defer-flag
+	      ;; If we can't process any text now,
+	      ;; save it for later.
+	      (setq gud-filter-pending-text
+		    (concat (or gud-filter-pending-text "") string))
+
+	    ;; If we have to ask a question during the processing,
+	    ;; defer any additional text that comes from the debugger
+	    ;; during that time.
+	    (let ((gud-filter-defer-flag t))
+	      ;; Process now any text we previously saved up.
+	      (if gud-filter-pending-text
+		  (setq string (concat gud-filter-pending-text string)
+		        gud-filter-pending-text nil))
 
-	    (with-current-buffer (process-buffer proc)
 	      ;; If we have been so requested, delete the debugger prompt.
 	      (save-restriction
 		(widen)
@@ -2887,23 +2894,22 @@ gud-filter
 
 	      ;; Let the comint filter do the actual insertion.
 	      ;; That lets us inherit various comint features.
-	      (comint-output-filter proc output))
-
-	    ;; Put the arrow on the source line.
-	    ;; This must be outside of the save-excursion
-	    ;; in case the source file is our current buffer.
-	    (if process-window
-		(with-selected-window process-window
-		  (gud-display-frame))
-	      ;; We have to be in the proper buffer, (process-buffer proc),
-	      ;; but not in a save-excursion, because that would restore point.
-	      (with-current-buffer (process-buffer proc)
-		(gud-display-frame))))
-
-	  ;; If we deferred text that arrived during this processing,
-	  ;; handle it now.
-	  (if gud-filter-pending-text
-	      (gud-filter proc ""))))))
+	      (comint-output-filter proc output)
+
+	      ;; Put the arrow on the source line.
+	      ;; This must be outside of the save-excursion
+	      ;; in case the source file is our current buffer.
+	      (if process-window
+		  (with-selected-window process-window
+		    (gud-display-frame))
+	        ;; We are in the proper buffer, (process-buffer proc),
+	        ;; but not in a save-excursion, because that would restore point.
+		(gud-display-frame)))
+
+	    ;; If we deferred text that arrived during this processing,
+	    ;; handle it now.
+	    (if gud-filter-pending-text
+	        (gud-filter proc "")))))))
 
 (defvar gud-minor-mode-type nil)
 (defvar gud-overlay-arrow-position nil)




This bug report was last modified today.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.