GDB/MI executing a python command

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

GDB/MI executing a python command

David Griffiths
Hi, I have a GDB/MI front-end and would like to execute a GDB Python
extension command. This command will then in turn issue a number of
gdb.execute commands itself (for reasons to do with storing state, it is
potentially easier this way than issuing multiple MI commands). I expected
that when I run gdb.execute with "to_string=True" that all the output would
be captured. But this is not the case - lots of stuff gets output on the MI
channel. For instance doing a stepi I get:

^running
*running,thread-id="all"
~"0x00007ff54501f1f5 in ?? ()\n"
*stopped,reason="end-stepping-range",frame={addr="0x00007ff54501f1f5",func="??",args=[]},thread-id="2",stopped-threads="all"

this is in addition to the captured gdb.execute reply.

Is there a way to disable this additional MI output whilst my command is
running? Or maybe a better way of doing this?

Thanks,

David

--

David Griffiths, Senior Software Engineer

Undo <https://undo.io> | Resolve even the most challenging software defects
with software flight recorder technology
Reply | Threaded
Open this post in threaded view
|

Re: GDB/MI executing a python command

Simon Marchi-4
On 2019-05-22 8:37 a.m., David Griffiths wrote:

> Hi, I have a GDB/MI front-end and would like to execute a GDB Python
> extension command. This command will then in turn issue a number of
> gdb.execute commands itself (for reasons to do with storing state, it is
> potentially easier this way than issuing multiple MI commands). I expected
> that when I run gdb.execute with "to_string=True" that all the output would
> be captured. But this is not the case - lots of stuff gets output on the MI
> channel. For instance doing a stepi I get:
>
> ^running
> *running,thread-id="all"
> ~"0x00007ff54501f1f5 in ?? ()\n"
> *stopped,reason="end-stepping-range",frame={addr="0x00007ff54501f1f5",func="??",args=[]},thread-id="2",stopped-threads="all"
>
> this is in addition to the captured gdb.execute reply.
>
> Is there a way to disable this additional MI output whilst my command is
> running? Or maybe a better way of doing this?
>
> Thanks,
>
> David
>

Hi David,

First of all, I must warn that issuing execution control commands (run, continue, step, etc)
in some particular context (e.g. in a breakpoint's stop method) is known to be problematic.
There should really be a good way to control the execution from Python, but there isn't as
of today.  If this works for your use case, then great, but know that is an unpaved road.

Second, I think that at least some of this output is expected and there's no way I know of disabling
it.  The ones starting with "*" and "~" are expected, because they asynchronous output sent to all
UIs to propagate information about state changes, not just the one UI issuing the command.

I am unsure about the "^running" though.  When I type "stepi" in an MI interpreter, I get
"^running", that's perhaps acceptable.  But in your case, the "stepi" from gdb.execute("stepi")
should not be executed by an MI interpreter, but by a CLI interpreter (I believe).  So your
"stepi" shouldn't produce an MI response.  And even if it was correct to reply with ^running,
it should probably end up in the returned string, as it is a direct response/output of your
command, not asynchronous output.

Finally, I am not sure what your use case is, but this patch series that is currently in
review might interest you:

https://sourceware.org/ml/gdb-patches/2019-05/threads.html#00313

It allows to implement MI commands in Python, allowing those commands to return proper
MI output that is consumed by the frontend.

Simon
Reply | Threaded
Open this post in threaded view
|

Re: GDB/MI executing a python command

Jan Vrany
Hi there,

On Thu, 2019-05-23 at 10:43 -0400, Simon Marchi wrote:

> On 2019-05-22 8:37 a.m., David Griffiths wrote:
> > Hi, I have a GDB/MI front-end and would like to execute a GDB Python
> > extension command. This command will then in turn issue a number of
> > gdb.execute commands itself (for reasons to do with storing state, it is
> > potentially easier this way than issuing multiple MI commands). I expected
> > that when I run gdb.execute with "to_string=True" that all the output would
> > be captured. But this is not the case - lots of stuff gets output on the MI
> > channel. For instance doing a stepi I get:
> >
> > ^running
> > *running,thread-id="all"
> > ~"0x00007ff54501f1f5 in ?? ()\n"
> > *stopped,reason="end-stepping-range",frame={addr="0x00007ff54501f1f5",func="??",args=[]},thread-id="2",stopped-threads="all"
> >
> > this is in addition to the captured gdb.execute reply.
> >
> > Is there a way to disable this additional MI output whilst my command is
> > running? Or maybe a better way of doing this?
> >
> > Thanks,
> >
> > David
> >
>
> Hi David,
>
> First of all, I must warn that issuing execution control commands (run, continue, step, etc)
> in some particular context (e.g. in a breakpoint's stop method) is known to be problematic.
> There should really be a good way to control the execution from Python, but there isn't as
> of today.  If this works for your use case, then great, but know that is an unpaved road.
>
> Second, I think that at least some of this output is expected and there's no way I know of disabling
> it.  The ones starting with "*" and "~" are expected, because they asynchronous output sent to all
> UIs to propagate information about state changes, not just the one UI issuing the command.
>
> I am unsure about the "^running" though.  When I type "stepi" in an MI interpreter, I get
> "^running", that's perhaps acceptable.  But in your case, the "stepi" from gdb.execute("stepi")
> should not be executed by an MI interpreter, but by a CLI interpreter (I believe).  So your
> "stepi" shouldn't produce an MI response.

I dont think so. In my opinion it *should* produce correct MI output.  If there's an MI channel
opened, whenever the inferior is run or stopped, there should be an MI event, no matter what.

Imagine you have an MI frontend and you execute, from CLI, a custom python command than in turn
does gdb.execute("stepi") - or worse, gdb.execute("cont"). Then inferior is running but MI frontend
still thinks it is stopped, making those two out of sync. This would lead in all sort of problems
like frontent would still show "stopped", when switching thread in UI would result an MI error when
trying to obtain stacktrace (which hard to handle, since all you get is a *localized* error message).
And so on.

>   And even if it was correct to reply with ^running,
> it should probably end up in the returned string, as it is a direct response/output of your
> command, not asynchronous output.

For the very same resason, it should be sent to MI channel. Maybe, it should be *also* be captured
in command output, but still MI frontend should be notified.

My 2c,

Jan

>
> Finally, I am not sure what your use case is, but this patch series that is currently in
> review might interest you:
>
> https://sourceware.org/ml/gdb-patches/2019-05/threads.html#00313
>
> It allows to implement MI commands in Python, allowing those commands to return proper
> MI output that is consumed by the frontend.
>
> Simon

Reply | Threaded
Open this post in threaded view
|

Re: GDB/MI executing a python command

Simon Marchi-4
On 2019-05-23 11:54 a.m., Jan Vrany wrote:
> I dont think so. In my opinion it *should* produce correct MI output.  If there's an MI channel
> opened, whenever the inferior is run or stopped, there should be an MI event, no matter what.
>
> Imagine you have an MI frontend and you execute, from CLI, a custom python command than in turn
> does gdb.execute("stepi") - or worse, gdb.execute("cont"). Then inferior is running but MI frontend
> still thinks it is stopped, making those two out of sync. This would lead in all sort of problems
> like frontent would still show "stopped", when switching thread in UI would result an MI error when
> trying to obtain stacktrace (which hard to handle, since all you get is a *localized* error message).
> And so on.

Yes, but that's what the *running notification is for.  I was talking about the ^running, which
is not a notification, but a reply to a command.  It is strange that the MI channel gets a reply
for a command it did not send.

Simon

Reply | Threaded
Open this post in threaded view
|

Re: GDB/MI executing a python command

Jan Vrany
On Thu, 2019-05-23 at 12:03 -0400, Simon Marchi wrote:

> On 2019-05-23 11:54 a.m., Jan Vrany wrote:
> > I dont think so. In my opinion it *should* produce correct MI output.  If there's an MI channel
> > opened, whenever the inferior is run or stopped, there should be an MI event, no matter what.
> >
> > Imagine you have an MI frontend and you execute, from CLI, a custom python command than in turn
> > does gdb.execute("stepi") - or worse, gdb.execute("cont"). Then inferior is running but MI frontend
> > still thinks it is stopped, making those two out of sync. This would lead in all sort of problems
> > like frontent would still show "stopped", when switching thread in UI would result an MI error when
> > trying to obtain stacktrace (which hard to handle, since all you get is a *localized* error message).
> > And so on.
>
> Yes, but that's what the *running notification is for.  I was talking about the ^running, which
> is not a notification, but a reply to a command.  It is strange that the MI channel gets a reply
> for a command it did not send.

Ah, I'm sorry! My eyes are failing me.
Then I of course agree.

Jan
>
> Simon
>