Subject: bug#11279: closed (Re: bug#11279: 24.0.95; GDB scripting doesn't work in "M-x gdb")

From: [email-masked] (GNU bug Tracking System)
Date: Fri, 20 Apr 2012 10:12:02 +0000

Your bug report

#11279: 24.0.95; GDB scripting doesn't work in "M-x gdb"

which was filed against the emacs package, has been closed.

The explanation is attached below, along with your original report.
If you require more details, please reply to [email-masked].

-- 
11279: http://debbugs.gnu.org/cgi/bugreport.cgi?bug=11279
GNU Bug Tracking System
Contact [email-masked] with problems

Subject: Re: bug#11279: 24.0.95; GDB scripting doesn't work in "M-x gdb"
From: Eli Zaretskii <[email-masked]>
To: Chong Yidong <[email-masked]>
Cc: [email-masked]
Date: Fri, 20 Apr 2012 13:11:22 +0300
List-Id: <debbugs-submit.debbugs.gnu.org>

> From: Chong Yidong <[email-masked]>
> Cc: [email-masked]
> Date: Fri, 20 Apr 2012 15:27:04 +0800
> 
> Eli Zaretskii <[email-masked]> writes:
> 
> > The patch below fixes this for me.  But because I know almost nothing
> > about comint, please someone who does eyeball the patch closely,
> > because it should go to the emacs-24 branch.
> 
> I eyeballed it and see no problems (aside from the docstring of
> `gdb-control-commands-regexp', which should have a leading complete
> sentence).

I fixed the doc string, thanks for the review.

> If your testing turns up no problems, please go ahead and
> commit.

Done, as revision 107872 on the emacs-24 branch.

Subject: 24.0.95; GDB scripting doesn't work in "M-x gdb"
From: Eli Zaretskii <[email-masked]>
To: [email-masked]
Date: Thu, 19 Apr 2012 19:03:59 +0300
List-Id: <debbugs-submit.debbugs.gnu.org>

I guess no one (including myself ;-) uses "M-x gdb" in Emacs 24,
because otherwise I can't believe this bug would go unnoticed for so
long.

To reproduce:

 emacs -Q
 M-x gdb RET /path/to/emacs RET
 break Fredraw_display RET
 commands
 end

That "end" should have ended the entry of breakpoint commands and
returned you to the "(gdb)" prompt, but it doesn't.

What happens is that when you type "end" (or any other command after
typing "commands"), gdb-mi sends to GDB the following MI command:

  -interpreter-exec console "end"\n

But when GDB saw the initial "commands" command, it entered an
internal reading loop in the CLI interpreter, which does not expect to
see "-interpreter-exec".  It expects to see an unadorned "end".  So
from GDB's perspective, the breakpoint commands never end.  The bottom
line is that you simply _cannot_ define breakpoint commands in "M-x gdb".

The same problem happens with other commands that read blocks of
commands terminated by "end", like "if", "while", "python", etc.

This is a bad regression wrt Emacs 23.4 (which didn't use GDB/MI, and
thus was free of this problem).

The patch below fixes this for me.  But because I know almost nothing
about comint, please someone who does eyeball the patch closely,
because it should go to the emacs-24 branch.

After applying this patch, there's still one annoyance, which only
shows on Posix hosts (not on Windows): the ">" prompts for more
commands don't show.  This happens because that's how GDB/MI seems to
behave: when its standard output is a console, it does not respond
with the ">" prompts.  In fact, it doesn't respond at all until it
sees "end".  (On Windows, where the connection between GDB and Emacs
uses pipes, GDB doesn't behave as if it were talking to a console.)
This may be a GDB bug or misfeature, but I think it's a separate issue
anyway.  Perhaps people who know this stuff in more depth could look
into this.

Here's the patch I propose to install on the emacs-24 branch:

------------------------------------------------------------
--- lisp/progmodes/gdb-mi.el~0	2012-03-14 08:25:30.000000000 +0200
+++ lisp/progmodes/gdb-mi.el	2012-04-19 14:33:24.673836800 +0300
@@ -604,6 +604,8 @@
         (set (make-local-variable 'gud-marker-filter) #'gud-gdb-marker-filter))
       (funcall filter proc string))))
 
+(defvar gdb-control-level 0)
+
 ;;;###autoload
 (defun gdb (command-line)
   "Run gdb on program FILE in buffer *gud-FILE*.
@@ -678,6 +680,7 @@
     (set-process-filter proc #'gdb--check-interpreter))
 
   (set (make-local-variable 'gud-minor-mode) 'gdbmi)
+  (set (make-local-variable 'gdb-control-level) 0)
   (setq comint-input-sender 'gdb-send)
   (when (ring-empty-p comint-input-ring) ; cf shell-mode
     (let ((hfile (expand-file-name (or (getenv "GDBHISTFILE")
@@ -1663,6 +1666,15 @@
   :group 'gdb)
 
 
+(defvar gdb-control-commands-regexp
+  (concat
+   "^\\("
+   "commands\\|if\\|while\\|define\\|document\\|python\\|"
+   "while-stepping\\|stepping\\|ws\\|actions"
+   "\\)\\([[:blank:]]+.*\\)?$")
+  "Regexp matching GDB commands that enter a recursive reading loop which
+does not expect commands to be prefixed by \"-interpreter-exec console\".")
+
 (defun gdb-send (proc string)
   "A comint send filter for gdb."
   (with-current-buffer gud-comint-buffer
@@ -1672,11 +1684,15 @@
   (if (not (string= "" string))
       (setq gdb-last-command string)
     (if gdb-last-command (setq string gdb-last-command)))
-  (if (string-match "^-" string)
-      ;; MI command
+  (if (or (string-match "^-" string)
+	  (> gdb-control-level 0))
+      ;; Either MI command or we are feeding GDB's recursive reading loop.
       (progn
 	(setq gdb-first-done-or-error t)
-	(process-send-string proc (concat string "\n")))
+	(process-send-string proc (concat string "\n"))
+	(if (and (string-match "^end$" string)
+		 (> gdb-control-level 0))
+	    (setq gdb-control-level (1- gdb-control-level))))
     ;; CLI command
     (if (string-match "\\\\$" string)
 	(setq gdb-continuation (concat gdb-continuation string "\n"))
@@ -1687,7 +1703,12 @@
         (if gdb-enable-debug
             (push (cons 'mi-send to-send) gdb-debug-log))
         (process-send-string proc to-send))
-      (setq gdb-continuation nil))))
+      (if (and (string-match "^end$" string)
+	       (> gdb-control-level 0))
+	  (setq gdb-control-level (1- gdb-control-level)))
+      (setq gdb-continuation nil)))
+  (if (string-match gdb-control-commands-regexp string)
+      (setq gdb-control-level (1+ gdb-control-level))))
 
 (defun gdb-mi-quote (string)
   "Return STRING quoted properly as an MI argument.

------------------------------------------------------------

In GNU Emacs 24.0.95.1 (i386-mingw-nt5.1.2600)
 of 2012-04-02 on HOME-C4E4A596F7
Windowing system distributor `Microsoft Corp.', version 5.1.2600
Configured using:
 `configure --with-gcc (3.4)'

Important settings:
  value of $LC_ALL: nil
  value of $LC_COLLATE: nil
  value of $LC_CTYPE: nil
  value of $LC_MESSAGES: nil
  value of $LC_MONETARY: nil
  value of $LC_NUMERIC: nil
  value of $LC_TIME: nil
  value of $LANG: ENU
  value of $XMODIFIERS: nil
  locale-coding-system: cp1255
  default enable-multibyte-characters: t

Major mode: Mail

Minor modes in effect:
  diff-auto-refine-mode: t
  flyspell-mode: t
  desktop-save-mode: t
  show-paren-mode: t
  display-time-mode: t
  tooltip-mode: t
  mouse-wheel-mode: t
  tool-bar-mode: t
  menu-bar-mode: t
  file-name-shadow-mode: t
  global-font-lock-mode: t
  font-lock-mode: t
  blink-cursor-mode: t
  auto-composition-mode: t
  auto-encryption-mode: t
  auto-compression-mode: t
  temp-buffer-resize-mode: t
  line-number-mode: t
  abbrev-mode: t

Recent input:
SPC p i t f a l l s SPC a l o n g SPC t h i s SPC r 
o u t e . ) M-q SPC SPC <backspace> <backspace> <return> 
<return> T I A <return> <up> <up> <up> <up> <up> <up> 
<up> <up> <up> <up> <up> <up> <up> <up> <up> <up> <C-left> 
<C-left> <C-left> <left> <left> <left> C-t <down> <M-right> 
<C-left> <left> SPC b e t w e e n SPC E m a c s SPC 
a n d M-d M-q <down> <down> <down> <right> <down> <down> 
<left> <left> , SPC a n d SPC a l s o SPC r e a r s 
SPC i t s SPC u g l y SPC h e a d SPC i n SPC o t h 
e r SPC s i t u a t i o n s M-q <down> <C-home> <down> 
<down> <down> <down> <down> <down> <down> <down> <down> 
<down> <down> <down> <down> <down> <down> <down> <down> 
<down> <down> <down> <down> <C-home> <C-down> <C-down> 
<C-down> <C-down> <C-down> <C-down> <C-down> <C-down> 
<C-down> <C-down> <C-down> <C-down> <C-down> <C-down> 
<C-down> <up> <up> <up> <up> <up> <up> <up> <down> 
<C-right> <C-right> <C-right> <C-right> <C-right> <C-right> 
<C-right> <C-right> <C-right> <M-backspace> f o r c 
e <C-right> <C-right> M-d <down> <C-left> <C-left> 
<C-left> <C-left> <C-left> <C-right> SPC ( w e SPC 
a l r e a d y SPC h a v e SPC a SPC s i m i l a r SPC 
h a c k SPC f o r SPC I n s i g h t ) M-q <down> <down> 
<down> <down> <down> <C-home> C-c C-s <switch-frame> 
<switch-frame> <help-echo> <help-echo> <help-echo> 
<help-echo> <switch-frame> <help-echo> <help-echo> 
<help-echo> <switch-frame> M-x r e p o r t - e m a 
c s - b u g <return>

Recent messages:
Auto-saving...done
Auto-saving...done
Auto-saving...done
Auto-saving...done
Mark set [3 times]
Sending...
Added to d:/usr/eli/rmail/SENT.MAIL
Sending email 
Sending email done
Sending...done

Load-path shadows:
None found.

Features:
(shadow emacsbug multi-isearch dabbrev network-stream starttls tls
smtpmail auth-source eieio assoc gnus-util password-cache mailalias
sendmail rmailout dired-x dired tcl nxml-uchnm rng-xsd xsd-regexp
rng-cmpct rng-nxml rng-valid rng-loc rng-uri rng-parse nxml-parse
rng-match rng-dt rng-util rng-pttrn nxml-ns nxml-mode nxml-outln
nxml-rap nxml-util nxml-glyph nxml-enc xmltok sgml-mode face-remap
org-wl org-w3m org-vm org-rmail org-mhe org-mew org-irc org-jsinfo
org-infojs org-html org-exp ob-exp org-exp-blocks find-func org-agenda
org-info org-gnus org-docview org-bibtex bibtex org-bbdb org byte-opt
warnings bytecomp byte-compile cconv macroexp advice help-fns
advice-preload ob-emacs-lisp ob-tangle ob-ref ob-lob ob-table
org-footnote org-src ob-comint ob-keys ob ob-eval org-pcomplete
pcomplete org-list org-faces org-compat org-entities org-macs cal-menu
calendar cal-loaddefs noutline outline arc-mode archive-mode diff-mode
conf-mode newcomment parse-time sh-script executable generic jka-compr
make-mode gud easy-mmode comint ansi-color ring texinfo vc-cvs
ld-script flyspell info autorevert vc-bzr cc-mode cc-fonts cc-guess
cc-menus cc-cmds cc-styles cc-align cc-engine cc-vars cc-defs
regexp-opt qp rmailsum rmailmm message format-spec rfc822 mml mml-sec
mm-decode mm-bodies mm-encode mailabbrev gmm-utils mailheader
mail-parse rfc2231 rmail rfc2047 rfc2045 ietf-drums mm-util mail-prsvr
mail-utils desktop server filecache mairix cus-edit easymenu cus-start
cus-load wid-edit saveplace midnight ispell generic-x paren battery
time time-date tooltip ediff-hook vc-hooks lisp-float-type mwheel
dos-w32 disp-table ls-lisp w32-win w32-vars tool-bar dnd fontset image
fringe lisp-mode register page menu-bar rfn-eshadow timer select
scroll-bar mouse jit-lock font-lock syntax facemenu font-core frame
cham georgian utf-8-lang misc-lang vietnamese tibetan thai tai-viet
lao korean japanese hebrew greek romanian slovak czech european
ethiopic indian cyrillic chinese case-table epa-hook jka-cmpr-hook
help simple abbrev minibuffer loaddefs button faces cus-face files
text-properties overlay sha1 md5 base64 format env code-pages mule
custom widget hashtable-print-readable backquote make-network-process
multi-tty emacs)