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

classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|

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

Bob Rossi
Hi,

The question I have is, how are people determining when GDB is ready for
the next
command when using the new-ui feature of GDB?
Are people parsing the CLI window for (gdb)?
Am I missing something obvious?

CGDB has historically used annotations to communicate with gdb.
This provided pre-prompt and post-prompt annotations to determine when the
GDB prompt
was available and ready for the next command.

A couple of years ago I decided to try to port CGDB from annotations to MI.
At the time I asked the GDB mailing list how to determine when GDB was
ready for the next
command, Pedro Alves wrote:
    GDB is ready for input when it prints the MI prompt.  There's one
prompt that is
    already printed after ^running that you should ignore. That's an
historical wart.
I got CGDB working but never completed the activity when I realized that
using -i=mi
caused GDB to no longer treat the terminal as an interactive terminal.
Meaning, GDB wouldn't do tab completion and/or ask the user if they were
ready to quit.

Now I'm considering trying this again using the GDB new-ui feature.
In this mode the CLI remains in the starting terminal and the MI is moved
to the new-ui tty.
I noticed that in the new-ui window, the MI end token (gdb)\n isn't put
out. Is this intentional?
In this mode, what's the proper way to determine if GDB is ready for
another command?

Thanks,
Bob Rossi
Reply | Threaded
Open this post in threaded view
|

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

Bob Rossi
Ping

On Tue, Oct 22, 2019 at 7:15 PM Robert Rossi <[hidden email]> wrote:

> Hi,
>
> The question I have is, how are people determining when GDB is ready for
> the next
> command when using the new-ui feature of GDB?
> Are people parsing the CLI window for (gdb)?
> Am I missing something obvious?
>
> CGDB has historically used annotations to communicate with gdb.
> This provided pre-prompt and post-prompt annotations to determine when the
> GDB prompt
> was available and ready for the next command.
>
> A couple of years ago I decided to try to port CGDB from annotations to MI.
> At the time I asked the GDB mailing list how to determine when GDB was
> ready for the next
> command, Pedro Alves wrote:
>     GDB is ready for input when it prints the MI prompt.  There's one
> prompt that is
>     already printed after ^running that you should ignore. That's an
> historical wart.
> I got CGDB working but never completed the activity when I realized that
> using -i=mi
> caused GDB to no longer treat the terminal as an interactive terminal.
> Meaning, GDB wouldn't do tab completion and/or ask the user if they were
> ready to quit.
>
> Now I'm considering trying this again using the GDB new-ui feature.
> In this mode the CLI remains in the starting terminal and the MI is moved
> to the new-ui tty.
> I noticed that in the new-ui window, the MI end token (gdb)\n isn't put
> out. Is this intentional?
> In this mode, what's the proper way to determine if GDB is ready for
> another command?
>
> Thanks,
> Bob Rossi
>
Reply | Threaded
Open this post in threaded view
|

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

Pedro Alves-7
In reply to this post by Bob Rossi
On 10/23/19 12:15 AM, Robert Rossi wrote:

> Hi,
>
> The question I have is, how are people determining when GDB is ready for
> the next
> command when using the new-ui feature of GDB?
> Are people parsing the CLI window for (gdb)?
> Am I missing something obvious?
>
> CGDB has historically used annotations to communicate with gdb.
> This provided pre-prompt and post-prompt annotations to determine when the
> GDB prompt
> was available and ready for the next command.
>
> A couple of years ago I decided to try to port CGDB from annotations to MI.
> At the time I asked the GDB mailing list how to determine when GDB was
> ready for the next
> command, Pedro Alves wrote:
>     GDB is ready for input when it prints the MI prompt.  There's one
> prompt that is
>     already printed after ^running that you should ignore. That's an
> historical wart.
> I got CGDB working but never completed the activity when I realized that
> using -i=mi
> caused GDB to no longer treat the terminal as an interactive terminal.
> Meaning, GDB wouldn't do tab completion and/or ask the user if they were
> ready to quit.
>
> Now I'm considering trying this again using the GDB new-ui feature.
> In this mode the CLI remains in the starting terminal and the MI is moved
> to the new-ui tty.
> I noticed that in the new-ui window, the MI end token (gdb)\n isn't put
> out. Is this intentional?
> In this mode, what's the proper way to determine if GDB is ready for
> another command?

I'm not sure what you mean -- I see the end token being put out?

Thanks,
Pedro Alves

Reply | Threaded
Open this post in threaded view
|

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

Bob Rossi
Huh. Here is my setup.

$ gdb --version
GNU gdb (GDB) 8.3.1

On terminal one with gdb I have,
  $ gdb  -q -ex "new-ui mi /dev/pts/11" ./test_main
  Reading symbols from ./test_main...
  New UI allocated
  (gdb)
Terminal 2 shows
  $ tty
  /dev/pts/13
  $ sleep 1000
  =thread-group-added,id="i1"
  (gdb) <--- Good

So far everything is good. Now in terminal one I make a breakpoint.

Terminal 1 shows
  (gdb) b main
  Breakpoint 1 at 0x4006c0: file test.cpp, line 42.
  (gdb)
Terminal 2 shows
  (gdb)

=breakpoint-created,bkpt={number="1",type="breakpoint",...,original-location="main"}
<--- No GDB prompt

However it has no gdb prompt.
Now, if I run the program,

Terminal 1 shows,
  (gdb) r
  Starting program:.../test_main

  Breakpoint 1, main (argc=1, argv=0x7fffffffdea8) at test.cpp:42
  42      {
  (gdb)
Terminal 2 shows
  =thread-group-started,id="i1",pid="25913"
  =thread-created,id="1",group-id="i1"
  =library-loaded,id=...
  =library-loaded,id="/lib/x86_6....
  ~"\n"
  ~"Breakpoint 1, main (argc=1, argv=0x7fffffffdea8) at test.cpp:42\n"
  ~"42\t{\n"
  *stopped,reason="breakpoint-hit",...stopped-threads="all",core="0"
  <-- No GDB prompt

In this case also there is no gdb prompt.

Is this expected behavior or an oversight?

Thanks,
Bob Rossi

On Tue, Oct 29, 2019 at 9:21 AM Pedro Alves <[hidden email]> wrote:

> On 10/23/19 12:15 AM, Robert Rossi wrote:
> > Hi,
> >
> > The question I have is, how are people determining when GDB is ready for
> > the next
> > command when using the new-ui feature of GDB?
> > Are people parsing the CLI window for (gdb)?
> > Am I missing something obvious?
> >
> > CGDB has historically used annotations to communicate with gdb.
> > This provided pre-prompt and post-prompt annotations to determine when
> the
> > GDB prompt
> > was available and ready for the next command.
> >
> > A couple of years ago I decided to try to port CGDB from annotations to
> MI.
> > At the time I asked the GDB mailing list how to determine when GDB was
> > ready for the next
> > command, Pedro Alves wrote:
> >     GDB is ready for input when it prints the MI prompt.  There's one
> > prompt that is
> >     already printed after ^running that you should ignore. That's an
> > historical wart.
> > I got CGDB working but never completed the activity when I realized that
> > using -i=mi
> > caused GDB to no longer treat the terminal as an interactive terminal.
> > Meaning, GDB wouldn't do tab completion and/or ask the user if they were
> > ready to quit.
> >
> > Now I'm considering trying this again using the GDB new-ui feature.
> > In this mode the CLI remains in the starting terminal and the MI is moved
> > to the new-ui tty.
> > I noticed that in the new-ui window, the MI end token (gdb)\n isn't put
> > out. Is this intentional?
> > In this mode, what's the proper way to determine if GDB is ready for
> > another command?
>
> I'm not sure what you mean -- I see the end token being put out?
>
> Thanks,
> Pedro Alves
>
>
Reply | Threaded
Open this post in threaded view
|

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

Jonah Graham
Hi Bob,

Robert Rossi <[hidden email]> wrote:
>
> The question I have is, how are people determining when GDB is ready for
> the next
> command when using the new-ui feature of GDB?
> Are people parsing the CLI window for (gdb)?
> Am I missing something obvious?
>

Eclipse CDT uses gdb for the backend debugger, and it does not actually use
the (gdb) prompt except to establish initial connection with gdb. After
that Eclipse tracks state of gdb to know when it can send commands. So in
your example, CDT looks for messages such as *stopped to know when gdb is
stopped and can accept commands. In non-stop mode you further track the
running threads to know which you can communicate with. For MI commands CDT
sends, it knows when they are done by tracking their ^done messages, it
also sends multiple commands at a time before waiting for answers.

> In this case also there is no gdb prompt.

This happens in the reverse case too, when MI issues a step or similar the
CLI terminal does not get a new (gdb) prompt.

> Is this expected behavior or an oversight?

I am used to this behaviour, but I can't comment on whether it is expected
or not, e.g I can type cont<enter> even though no fresh (gdb) prompt:

(gdb)
Breakpoint 5, main () at ../src/helloworld.c:26
26              printf("&x=%p\n", &x);
cont
Continuing.
[Inferior 1 (process 15248) exited normally]
(gdb)

HTH
Jonah
Reply | Threaded
Open this post in threaded view
|

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

Pedro Alves-7
In reply to this post by Bob Rossi
On 11/2/19 10:35 AM, Robert Rossi wrote:

> Huh. Here is my setup.
>
> $ gdb --version
> GNU gdb (GDB) 8.3.1
>
> On terminal one with gdb I have,
>   $ gdb  -q -ex "new-ui mi /dev/pts/11" ./test_main
>   Reading symbols from ./test_main...
>   New UI allocated
>   (gdb)
> Terminal 2 shows
>   $ tty
>   /dev/pts/13
>   $ sleep 1000
>   =thread-group-added,id="i1"
>   (gdb) <--- Good
>
> So far everything is good. Now in terminal one I make a breakpoint.
>
> Terminal 1 shows
>   (gdb) b main
>   Breakpoint 1 at 0x4006c0: file test.cpp, line 42.
>   (gdb)
> Terminal 2 shows
>   (gdb)
>
> =breakpoint-created,bkpt={number="1",type="breakpoint",...,original-location="main"}
> <--- No GDB prompt
>
> However it has no gdb prompt.

A gdb prompt indicates that GDB is ready to accept commands
again.

Here you have an asynchronous notification, which can appear
at any time.  GDB never stopped accepting commands since that
initial prompt.  So no new prompt.

> Now, if I run the program,
>
> Terminal 1 shows,
>   (gdb) r
>   Starting program:.../test_main
>
>   Breakpoint 1, main (argc=1, argv=0x7fffffffdea8) at test.cpp:42
>   42      {
>   (gdb)
> Terminal 2 shows
>   =thread-group-started,id="i1",pid="25913"
>   =thread-created,id="1",group-id="i1"
>   =library-loaded,id=...
>   =library-loaded,id="/lib/x86_6....
>   ~"\n"
>   ~"Breakpoint 1, main (argc=1, argv=0x7fffffffdea8) at test.cpp:42\n"
>   ~"42\t{\n"
>   *stopped,reason="breakpoint-hit",...stopped-threads="all",core="0"
>   <-- No GDB prompt
>
> In this case also there is no gdb prompt.

Same thing here.  These are all asynchronous notifications.  GDB
is accepting MI commands before and after all these notifications,
even if the CLI channel isn't.  E.g., if you run a program that
doesn't hit a breakpoint, you'll get on the CLI:

(gdb) r
Starting program: /tmp/infinite-loop
iter 1
iter 2
iter 3
iter 4
...

while on the MI channel you get:

...
*running,thread-id="all"

and you can still issue commands there, while the program
is running:

 -data-evaluate-expression 1
 ^done,value="1"
 (gdb)


>
> Is this expected behavior or an oversight?
>
It's expected.

Thanks,
Pedro Alves

Reply | Threaded
Open this post in threaded view
|

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

Bob Rossi
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?

Thanks,
Bob Rossi
Reply | Threaded
Open this post in threaded view
|

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

Sourceware - gdb list mailing list
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