Re: gdb/mi, new-ui. the console and determining when GDB is ready for the next command

Pedro Alves
2020-04-11T14:09:11Z

On 4/11/20 1:12 PM, Bob Rossi wrote:
> On Tue, Nov 05, 2019 at 02:06:30PM +0000, Pedro Alves wrote:
>> On 11/2/19 10:35 AM, Robert Rossi wrote:
>>> ...
>>> =breakpoint-created,bkpt={number="1",type="breakpoint",...,original-location="main"}
>>> <--- No GDB prompt
>>
>> A gdb prompt indicates that GDB is ready to accept commands
>> again.
>
> Sorry to respond to such an old thread. I'm just getting back into
> this somehow.
>
> The above statement surprises me. The MI manual describes an MI
> output command with the following syntax,
> output ->
> ( out-of-band-record )* [ result-record ] "(gdb)" nl
> So I'm expecting "(gdb)\n" followed by the end of every output
> command. Is this not how it works?

=breakpoint-created is an out-of-band-record, not a result-record.
"(gdb)" will follow a result-record, but since result-records
are results/responses to MI commands initiated from the MI client,
and in this case there was no MI command initiated from the MI
client, there's no result-record, and thus no (gdb) prompt either.

Right above that, it says:

@cindex output syntax of @sc{gdb/mi}
@cindex @sc{gdb/mi}, output syntax
The output from @sc{gdb/mi} consists of zero or more out-of-band records
followed, optionally, by a single result record. This result record
is for the most recent command. The sequence of output records is
terminated by @samp{(gdb)}.

I suppose this was written before mi-async was a thing, and should be
clarified. Note that further below it also says:

Frontends should treat all async output as reporting general changes
in the state of the target and there should be no need to associate async
output to any prior command.

This is what is happening in the new-ui case. The =breakpoint-created
async notification is reporting about a change in the state, and it
not a response to any prior MI command.

Note also that this is not specific to new-ui. With regular MI, on
GNU/Linux you get for example:

-exec-run
=thread-group-started,id="i1",pid="527"
=thread-created,id="1",group-id="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",ranges=[{from="0x00007ffff7dd8d50",to="0x00007ffff7df5520"}]
^running
*running,thread-id="all"
(gdb) <<<<<<< GDB is ready to process further MI commands while the target is running
=library-loaded,id="/lib64/libpthread.so.0",target-name="/lib64/libpthread.so.0",host-name="/lib64/libpthread.so.0",symbols-loaded="0",thread-group="i1",ranges=[{from="0x00007ffff7bbfb10",to="0x00007ffff7bcd951"}]
=library-loaded,id="/lib64/libc.so.6",target-name="/lib64/libc.so.6",host-name="/lib64/libc.so.6",symbols-loaded="0",thread-group="i1",ranges=[{from="0x00007ffff78247d0",to="0x00007ffff796569c"}]
~"[Thread debugging using libthread_db enabled]\n"
~"Using host libthread_db library \"/lib64/libthread_db.so.1\".\n"
=thread-created,id="2",group-id="i1"
~"[New Thread 0x7ffff7803700 (LWP 531)]\n"
*running,thread-id="2"
=thread-created,id="3",group-id="i1"
~"[New Thread 0x7ffff7002700 (LWP 532)]\n"
*running,thread-id="3"

Note how all those out-of-band-records (=library-loaded, =thread-created,
*running, ~"foo", etc.) show up after the "(gdb)" prompt, while the target
is running, and there's no (gdb) at the "end" (there's really no "end" here,
since the program is running, and any sort of async events can be reported
in response to whatever the target program does.)

Pedro Alves