Subject: bug#29020: 25.1; gdb-mi doesn't display prompt when attaching

From: Mike Gulick <[email-masked]>
Date: Thu, 26 Oct 2017 17:43:31 -0400

When attaching to a process from gdb-mi, the (gdb) prompt is not shown
after the attach command completes.

This creates confusion because it appears that GDB is still working.  A
common reaction is to hit 'Enter', which re-sends the last command,
i.e. 'attach PID', which kills the process that you were attempting to
debug.

$ gdb --version
GNU gdb (Debian 7.12-6) 7.12.0.20161007-git

$ sleep 1000 &
[1] 9924

$ emacs -Q

M-x gdb
Run gdb (like this): gdb -i=mi -n

*gud* buffer output:

  Current directory is /usr/share/emacs/25.1/lisp/progmodes/
  GNU gdb (Debian 7.12-6) 7.12.0.20161007-git
  ...
  (gdb) attach 9924
  Attaching to process 9924
  (gdb) Reading symbols from /bin/sleep...(no debugging symbols found)...done.
  Reading symbols from /lib/x86_64-linux-gnu/libc.so.6...Reading symbols from /usr/lib/debug/.build-id/79/450f6e36287865d093ea209b85a222209925ff.debug...done.
  done.
  Reading symbols from /lib64/ld-linux-x86-64.so.2...Reading symbols from /usr/lib/debug/.build-id/6f/150f33b150d6a81e26a425dd47d713d00f2d29.debug...done.
  done.
  0x00007f8f29196230 in __nanosleep_nocancel () at ../sysdeps/unix/syscall-template.S:84
  84	../sysdeps/unix/syscall-template.S: No such file or directory.

Notice that the prompt is displayed after "Attaching to process 9924",
but it is then obscured by additional information printed by gdb.

The gdb-mi output (captured by running 'set logging on' from gdb
prompt'):

  (gdb) 
  ~"Attaching to process 31331\n"
  =thread-group-started,id="i1",pid="31331"
  =thread-created,id="1",group-id="i1"
  ^done
  ~"Reading symbols from /bin/sleep..."
  ~"(no debugging symbols found)...done.\n"
  =library-loaded,id="/lib/x86_64-linux-gnu/libc.so.6",target-name="/lib/x86_64-linux-gnu/libc.so.6",host-name="/lib/x86_64-linux-gnu/libc.so.6",symbols-loaded="0",thread-group="i1"
  =library-loaded,id="/lib64/ld-linux-x86-64.so.2",target-name="/lib64/ld-linux-x86-64.so.2",host-name="/lib64/ld-linux-x86-64.so.2",symbols-loaded="0",thread-group="i1"
  ~"Reading symbols from /lib/x86_64-linux-gnu/libc.so.6..."
  ~"Reading symbols from /usr/lib/debug/.build-id/79/450f6e36287865d093ea209b85a222209925ff.debug..."
  ~"done.\n"
  ~"done.\n"
  ~"Reading symbols from /lib64/ld-linux-x86-64.so.2..."
  ~"Reading symbols from /usr/lib/debug/.build-id/6f/150f33b150d6a81e26a425dd47d713d00f2d29.debug..."
  ~"done.\n"
  ~"done.\n"
  ~"0x00007f8d63e86230 in __nanosleep_nocancel () at ../sysdeps/unix/syscall-template.S:84\n"
  &"84\t../sysdeps/unix/syscall-template.S: No such file or directory.\n"
  *stopped,frame={addr="0x00007f8d63e86230",func="__nanosleep_nocancel",args=[],file="../sysdeps/unix/syscall-template.S",fullname="/build/glibc-p3Km7c/glibc-2.24/posix/../sysdeps/unix/syscall-template.S",line="84"},thread-id="1",stopped-threads="all",core="9"
  33^done,frame={level="0",addr="0x00007f8d63e86230",func="__nanosleep_nocancel",file="../sysdeps/unix/syscall-template.S",fullname="/build/glibc-p3Km7c/glibc-2.24/posix/../sysdeps/unix/syscall-template.S",line="84"}
  (gdb) 
  34^done,threads=[{id="1",target-id="process 31331",name="sleep",frame={level="0",addr="0x00007f8d63e86230",func="__nanosleep_nocancel",args=[],file="../sysdeps/unix/syscall-template.S",fullname="/build/glibc-p3Km7c/glibc-2.24/posix/../sysdeps/unix/syscall-template.S",line="84"},state="stopped",core="9"}],current-thread-id="1"
  (gdb) 
  35^done,BreakpointTable={nr_rows="0",nr_cols="6",hdr=[{width="7",alignment="-1",col_name="number",colhdr="Num"},{width="14",alignment="-1",col_name="type",colhdr="Type"},{width="4",alignment="-1",col_name="disp",colhdr="Disp"},{width="3",alignment="-1",col_name="enabled",colhdr="Enb"},{width="10",alignment="-1",col_name="addr",colhdr="Address"},{width="40",alignment="2",col_name="what",colhdr="What"}],body=[]}
  (gdb) 
  36^done,register-names=["rax","rbx","rcx","rdx","rsi","rdi","rbp","rsp","r8","r9","r10","r11","r12","r13","r14","r15","rip","eflags","cs","ss","ds","es","fs","gs","st0","st1","st2","st3","st4","st5","st6","st7","fctrl","fstat","ftag","fiseg","fioff","foseg","fooff","fop","xmm0","xmm1","xmm2","xmm3","xmm4","xmm5","xmm6","xmm7","xmm8","xmm9","xmm10","xmm11","xmm12","xmm13","xmm14","xmm15","mxcsr","ymm0h","ymm1h","ymm2h","ymm3h","ymm4h","ymm5h","ymm6h","ymm7h","ymm8h","ymm9h","ymm10h","ymm11h","ymm12h","ymm13h","ymm14h","ymm15h","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","orig_rax","al","bl","cl","dl","sil","dil","bpl","spl","r8l","r9l","r10l","r11l","r12l","r13l","r14l","r15l","ah","bh","ch","dh","ax","bx","cx","dx","si","di","bp","","r8w","r9w","r10w","r11w","r12w","r13w","r14w","r15w","eax","ebx","ecx","edx","esi","edi","ebp","esp","r8d","r9d","r10d","r11d","r12d","r13d","r14d","r15d","ymm0","ymm1","ymm2","ymm3","ymm4","ymm5","ymm6","ymm7","ymm8","ymm9","ymm10","ymm11","ymm12","ymm13","ymm14","ymm15"]
  (gdb) 

In gdb-mi.el, the variable 'gdb-first-done-or-error' is set to nil after
the first '^done' is printed.  When parsing '*stopped' in gdb-stopped,
the prompt is only printed if gdb-first-done-or-error is 't'.  Since
this output stream contains '^done', followed by some more output,
followed by '*stopped', the gdb prompt is not being re-printed when
'*stopped' is encountered.  If I temporarily change the following lines
in gdb-stopped in gdb-mi.el, then the prompt is printed after attaching:

--- /tmp/gdb-mi.el.orig	2017-10-26 17:26:27.955626830 -0400
+++ /tmp/gdb-mi.el	2017-10-26 17:25:27.715228866 -0400
@@ -2537,8 +2537,7 @@
           (message "Thread %s stopped" thread-id))))
 
     ;; Print "(gdb)" to GUD console
-    (when gdb-first-done-or-error
-      (setq gdb-filter-output (concat gdb-filter-output gdb-prompt-name)))
+    (setq gdb-filter-output (concat gdb-filter-output gdb-prompt-name))
 
     ;; In non-stop, we update information as soon as another thread gets
     ;; stopped

This naive change may have other side-effects, which I did not fully
think through, but it does at least show what the issue is.  Another
possible solution is that 'gdb-first-done-or-error', which controls
whether the prompt should be printed on the next '^done', '^error', or
'*stopped', should be reset to 't' whenever anything is printed to the
gud buffer.  However I was unable to figure out how to make that work.

Thanks for your consideration.

-Mike

In GNU Emacs 25.1.1 (x86_64-pc-linux-gnu, GTK+ Version 3.22.11)
 of 2017-09-15, modified by Debian built on trouble
Windowing system distributor 'The X.Org Foundation', version 11.0.11903000
System Description:	Debian GNU/Linux 9.1 (stretch)

Configured using:
 'configure --build x86_64-linux-gnu --prefix=/usr
 --sharedstatedir=/var/lib --libexecdir=/usr/lib
 --localstatedir=/var/lib --infodir=/usr/share/info
 --mandir=/usr/share/man --with-pop=yes
 --enable-locallisppath=/etc/emacs25:/etc/emacs:/usr/local/share/emacs/25.1/site-lisp:/usr/local/share/emacs/site-lisp:/usr/share/emacs/25.1/site-lisp:/usr/share/emacs/site-lisp
 --with-sound=alsa --build x86_64-linux-gnu --prefix=/usr
 --sharedstatedir=/var/lib --libexecdir=/usr/lib
 --localstatedir=/var/lib --infodir=/usr/share/info
 --mandir=/usr/share/man --with-pop=yes
 --enable-locallisppath=/etc/emacs25:/etc/emacs:/usr/local/share/emacs/25.1/site-lisp:/usr/local/share/emacs/site-lisp:/usr/share/emacs/25.1/site-lisp:/usr/share/emacs/site-lisp
 --with-sound=alsa --with-x=yes --with-x-toolkit=gtk3
 --with-toolkit-scroll-bars 'CFLAGS=-g -O2
 -fdebug-prefix-map=/build/emacs25-wN2qS3/emacs25-25.1+1=. -fstack-protector-strong
 -Wformat -Werror=format-security -Wall' 'CPPFLAGS=-Wdate-time
 -D_FORTIFY_SOURCE=2' LDFLAGS=-Wl,-z,relro'

Configured features:
XPM JPEG TIFF GIF PNG RSVG IMAGEMAGICK SOUND GPM DBUS GCONF GSETTINGS
NOTIFY ACL LIBSELINUX GNUTLS LIBXML2 FREETYPE M17N_FLT LIBOTF XFT ZLIB
TOOLKIT_SCROLL_BARS GTK3 X11

Important settings:
  value of $LC_COLLATE: C
  value of $LANG: en_US.UTF-8
  locale-coding-system: utf-8-unix

Major mode: Debugger

Minor modes in effect:
  tooltip-mode: t
  global-eldoc-mode: t
  electric-indent-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
  line-number-mode: t
  transient-mark-mode: t

Recent messages:
Auto-saving...
Auto-saving gdb-mi.el.gz: Opening output file: Permission denied, /usr/share/emacs/25.1/lisp/progmodes/#gdb-mi.el.gz#
Quit
C-; is undefined
Undo!
Mark set [2 times]
gdb-stopped
Target doesn’t support non-stop mode.  Turning it off.
Switched to thread 1
ptrace: No such process.

Load-path shadows:
None found.

Features:
(shadow sort mail-extr emacsbug message dired format-spec rfc822 mml
mml-sec password-cache epg epg-config gnus-util mm-decode mm-bodies
mm-encode mail-parse rfc2231 mailabbrev gmm-utils mailheader sendmail
rfc2047 rfc2045 ietf-drums mm-util help-fns mail-prsvr mail-utils
jka-compr thingatpt find-func cl-seq gdb-mi bindat json map seq byte-opt
gv bytecomp byte-compile cl-extra help-mode easymenu cconv cl-loaddefs
pcase cl-lib gud easy-mmode comint ansi-color ring time-date mule-util
tooltip eldoc electric uniquify ediff-hook vc-hooks lisp-float-type
mwheel x-win term/common-win x-dnd tool-bar dnd fontset image regexp-opt
fringe tabulated-list newcomment elisp-mode lisp-mode prog-mode register
page menu-bar rfn-eshadow timer select scroll-bar mouse jit-lock
font-lock syntax facemenu font-core frame cl-generic cham georgian
utf-8-lang misc-lang vietnamese tibetan thai tai-viet lao korean
japanese eucjp-ms cp51932 hebrew greek romanian slovak czech european
ethiopic indian cyrillic chinese charscript case-table epa-hook
jka-cmpr-hook help simple abbrev minibuffer cl-preloaded nadvice
loaddefs button faces cus-face macroexp files text-properties overlay
sha1 md5 base64 format env code-pages mule custom widget
hashtable-print-readable backquote dbusbind inotify dynamic-setting
system-font-setting font-render-setting move-toolbar gtk x-toolkit x
multi-tty make-network-process emacs)

Memory information:
((conses 16 108410 11828)
 (symbols 48 21790 0)
 (miscs 40 75 270)
 (strings 32 21724 5215)
 (string-bytes 1 614894)
 (vectors 16 15131)
 (vector-slots 8 463120 6883)
 (floats 8 192 261)
 (intervals 56 756 11)
 (buffers 976 20))