Bug 29002 - Console input broken in MI mode
Summary: Console input broken in MI mode
Status: RESOLVED FIXED
Alias: None
Product: gdb
Classification: Unclassified
Component: mi (show other bugs)
Version: HEAD
: P2 normal
Target Milestone: 12.1
Assignee: Andrew Burgess
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2022-03-27 05:33 UTC by Eli Zaretskii
Modified: 2023-07-13 14:05 UTC (History)
2 users (show)

See Also:
Host: i686-pc-mingw32
Target: i686-pc-mingw32
Build: i686-pc-mingw32
Last reconfirmed:


Attachments
Provisional patch to solve the broken console input in MI mode (388 bytes, patch)
2022-03-27 06:20 UTC, Eli Zaretskii
Details | Diff
More thorough patch to fix the gdb-mi problem as well (493 bytes, patch)
2022-03-27 09:52 UTC, Eli Zaretskii
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Eli Zaretskii 2022-03-27 05:33:05 UTC
In the GDB-12.0.90 pretest built with mingw.org's MinGW as 32-bit MS-Windows program, console input in MI mode is badly broken:

  (gdb)
  r -Q
  &"g\n"
  &"Ambiguous command \"g\": gcore, generate-core-file, goto-bookmark, gr, gu, guile, guile-repl.\n"
  ^error,msg="Ambiguous command \"g\": gcore, generate-core-file, goto-bookmark, gr, gu, guile, guile-repl."

As can be seen, no matter what I type, GDB thinks I typed "g\n", and reacts accordingly.  This means I cannot even quit GDB normally, only kill it.

There's no such problems using the CLI interpreter, only when invoking GDB with the -i=mi switch.
Comment 1 Eli Zaretskii 2022-03-27 06:20:07 UTC
Created attachment 14037 [details]
Provisional patch to solve the broken console input in MI mode
Comment 2 Eli Zaretskii 2022-03-27 06:23:51 UTC
The culprit is this commit:

  commit d08cbc5d3203118da5583296e49273cf82378042
  Author:     Andrew Burgess <aburgess@redhat.com>
  AuthorDate: Wed Dec 22 12:57:44 2021 +0000
  Commit:     Andrew Burgess <aburgess@redhat.com>
  CommitDate: Mon Feb 7 10:24:27 2022 +0000

      gdb: unbuffer all input streams when not using readline

I guess the detailed analysis in that commit, which describes the behavior of glibc and the Linux kernel, doesn't fully apply to MS-Windows and its C runtime...

The patch I proposed, which partially reverts that commit, fixes the issue for me on MS-Windows.  But if we want to keep the current code for GNU/Linux and other platforms, I guess the actual fix will need to be more complex.
Comment 3 Eli Zaretskii 2022-03-27 09:48:44 UTC
But this is not the whole story.  That commit also causes the Emacs gdb-mi front-end to GDB to become broken, at least on MS-Windows.

What happens is that gdb-mi sends, via the GDB/MI interface, several commands in a sequence when the debugging session begins.  Those commands are:

  1-gdb-set new-console off
  2-gdb-set interactive-mode on
  3-gdb-set height 0
  4-enable-pretty-printing
  5-enable-frame-filters
  6-file-list-exec-source-file
  7-gdb-show prompt
  8-stack-info-frame
  9-thread-info
  10-break-list
  11-thread-info
  12-break-list

But when GDB responds to those commands, some of the responses have the first character of the TOKEN part stripped.  Here's what Emacs receives in response (this is a single string sent to Emacs in one go):

1^done
(gdb) 
2^done
(gdb) 
3^done
(gdb) 
^done
(gdb) 
5^done
(gdb) 
^done,line=\"1189\",file=\"emacs.c\",fullname=\"d:\\\\gnu\\\\git\\\\emacs\\\\branch\\\\src\\\\emacs.c\",macro-info=\"1\"
(gdb) 
7^done,value=\"(gdb) \"
(gdb) 
8^error,msg=\"No registers.\"
(gdb) 
^done,threads=[]
(gdb) 
0^done,BreakpointTable={nr_rows=\"1\",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=[bkpt={number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"0x0115dc0c\",func=\"terminate_due_to_signal\",file=\"emacs.c\",fullname=\"d:\\\\gnu\\\\git\\\\emacs\\\\branch\\\\src\\\\emacs.c\",line=\"400\",thread-groups=[\"i1\"],times=\"0\",original-location=\"terminate_due_to_signal\"}]}
(gdb) 
1^done,threads=[]
(gdb) 
12^done,BreakpointTable={nr_rows=\"1\",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=[bkpt={number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"0x0115dc0c\",func=\"terminate_due_to_signal\",file=\"emacs.c\",fullname=\"d:\\\\gnu\\\\git\\\\emacs\\\\branch\\\\src\\\\emacs.c\",line=\"400\",thread-groups=[\"i1\"],times=\"0\",original-location=\"terminate_due_to_signal\"}]}

Note that responses to 4, 6, and 9 don't have the TOKEN part, and responses to 10 and 11 have the first digit, 1, removed from TOKEN, so they appear as if the TOKEN were 0 (which is invalid) and 1 (which was already received, and so is not expected at this time).

It turns out that restoring the "done_once" part of the offending commit fixes this problem as well.  I'm guessing that the repeated calls to `setbuf` cause those characters to be lost, perhaps because `setbuf` flushes the stream, which for an input stream means it empties the buffer.  And we do call `setbuf` in this scenario, because interaction between Emacs and GDB in this case is via pipes.

In general, AFAIK the C standard allows to call `setvbuf` (and thus `setbuf`) only once, before any I/O operation was done for a given stream.  But after the commit mentioned above, we call `setbuf` multiple times.

So the proposed patch now changes to an almost full revert of the offending commit, see the attachment.
Comment 4 Eli Zaretskii 2022-03-27 09:52:01 UTC
Created attachment 14039 [details]
More thorough patch to fix the gdb-mi problem as well
Comment 5 Sourceware Commits 2022-04-24 15:43:10 UTC
The master branch has been updated by Joel Brobecker <brobecke@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=ac16b09d7e5fd0013ffa27e4d0531c0af12a529a

commit ac16b09d7e5fd0013ffa27e4d0531c0af12a529a
Author: Andrew Burgess <aburgess@redhat.com>
Date:   Sun Apr 24 08:39:19 2022 -0700

    gdb: move setbuf calls out of gdb_readline_no_editing_callback
    
    After this commit:
    
      commit d08cbc5d3203118da5583296e49273cf82378042
      Date:   Wed Dec 22 12:57:44 2021 +0000
    
          gdb: unbuffer all input streams when not using readline
    
    Issues were reported with some MS-Windows hosts, see the thread
    starting here:
    
      https://sourceware.org/pipermail/gdb-patches/2022-March/187004.html
    
    Filed in bugzilla as: PR mi/29002
    
    The problem seems to be that calling setbuf on terminal file handles
    is not always acceptable, see this mail for more details:
    
      https://sourceware.org/pipermail/gdb-patches/2022-April/187310.html
    
    This commit does two things, first moving the setbuf calls out of
    gdb_readline_no_editing_callback so that we don't end up calling
    setbuf so often.
    
    Then, for MS-Windows hosts, we don't call setbuf for terminals, this
    appears to resolve the issues that have been reported.
    
    Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=29002
Comment 6 Sourceware Commits 2022-04-24 15:44:19 UTC
The gdb-12-branch branch has been updated by Joel Brobecker <brobecke@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=e312dfbe9556d8e4557abe7fd3f1a4681e15da06

commit e312dfbe9556d8e4557abe7fd3f1a4681e15da06
Author: Andrew Burgess <aburgess@redhat.com>
Date:   Sun Apr 24 08:39:19 2022 -0700

    gdb: move setbuf calls out of gdb_readline_no_editing_callback
    
    After this commit:
    
      commit d08cbc5d3203118da5583296e49273cf82378042
      Date:   Wed Dec 22 12:57:44 2021 +0000
    
          gdb: unbuffer all input streams when not using readline
    
    Issues were reported with some MS-Windows hosts, see the thread
    starting here:
    
      https://sourceware.org/pipermail/gdb-patches/2022-March/187004.html
    
    Filed in bugzilla as: PR mi/29002
    
    The problem seems to be that calling setbuf on terminal file handles
    is not always acceptable, see this mail for more details:
    
      https://sourceware.org/pipermail/gdb-patches/2022-April/187310.html
    
    This commit does two things, first moving the setbuf calls out of
    gdb_readline_no_editing_callback so that we don't end up calling
    setbuf so often.
    
    Then, for MS-Windows hosts, we don't call setbuf for terminals, this
    appears to resolve the issues that have been reported.
    
    Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=29002
Comment 7 Joel Brobecker 2022-04-24 15:46:08 UTC
Andrew's patch now pushed to both master and gdb-12.
Comment 8 hmb 2023-07-11 13:01:59 UTC
I'm still encountering an error with the latest 13.2 release of GDB on a Windows host. When using GDB, I'm not receiving responses for the MI commands, causing my IDE (Eclipse) to freeze and become unresponsive.

To reproduce the issue, I have the following scenario in PowerShell:

$  cat input
1-list-thread-groups
2-list-thread-groups
3-list-thread-groups

cat input | arm-none-eabi-gdb.exe --silent --interpreter=mi2
=thread-group-added,id="i1"
(gdb)
1^done,groups=[{id="i1",type="process"}]
(gdb)
&"warning: Exception condition detected on fd 0\n"
&"error detected on stdin\n"



As observed, there is no response for the MI commands numbered 2 and 3."
Comment 10 Eli Zaretskii 2023-07-11 15:38:18 UTC
(In reply to hmb from comment #8)
> I'm still encountering an error with the latest 13.2 release of GDB on a
> Windows host. When using GDB, I'm not receiving responses for the MI
> commands, causing my IDE (Eclipse) to freeze and become unresponsive.
> 
> To reproduce the issue, I have the following scenario in PowerShell:
> 
> $  cat input
> 1-list-thread-groups
> 2-list-thread-groups
> 3-list-thread-groups
> 
> cat input | arm-none-eabi-gdb.exe --silent --interpreter=mi2
> =thread-group-added,id="i1"
> (gdb)
> 1^done,groups=[{id="i1",type="process"}]
> (gdb)
> &"warning: Exception condition detected on fd 0\n"
> &"error detected on stdin\n"
> 
> 
> 
> As observed, there is no response for the MI commands numbered 2 and 3."

I cannot reproduce this with GDB 13.1 I built myself with mingw.org's MinGW.  For the same input, but using the native MS-Windows GDB, I get this:

d:\usr>cat gdb.input | gdb  --silent --interpreter=mi2
=thread-group-added,id="i1"
(gdb)
1^done,groups=[{id="i1",type="process"}]
(gdb)
2^done,groups=[{id="i1",type="process"}]
(gdb)
3^done,groups=[{id="i1",type="process"}]
(gdb)
&"warning: Exception condition detected on fd 0\n"
&"error detected on stdin\n"

So all the 3 commands were processed.

In case it's important, I ran this command from cmd.exe, not from PowerShell.
Comment 11 hmb 2023-07-13 14:05:43 UTC
Upon further investigation, I have determined that the issue reported in this bug is not related to the upstream GDB project. The problem actually resides in our local patch or configuration.