Re: [MI non-stop 06/11, RFA/RFC] Report non-stop availability, and allow to enable everything with one command.

Pedro Alves
2008-08-05T16:31:20Z

On Monday 04 August 2008 13:58:57, Vladimir Prus wrote:
> The question is why the connection setup needs to know if we're in
> non-stop, and why -- which question we discuss below.

To tell the stub which mode it should enable, and to give it the
option to refuse working in all-stop mode.

> I think we can implement a scheme where a target say it does not know
> if non-stop is supported until connecting, and have the target set non_stop
> to zero if it's actually not supported. Something like probing for packets
> in remote protocol.

We for sure know that no target supports it, except for linux and
remote. The issue is which target do you ask, before connecting, since
the default run target may or may not support it. (e.g., linux -> remote,
vs mingw32 -> remote, where the stub on the remote side is the same, and
gdb is also configured with a native debugger included).

> > > 2. Make 'set non-stop 1' work even if the target has execution. I
> > > actually not sure why the error is emitted currently.
> >
> > Because at the current state of inferior control, it is hard to move
> > between non-stop <-> all-stop when there's already an inferior under
> > control. That may change, especially after getting rid of
> > context-switching (Real Soon Now (TM)) but that's how things are
> > currently.
>

> Well, if that might change then probably (2) is the right approach, and we
> should wait for your changes to land?

Let's just plan the commands and state vars to be able to do it in
the future.

> Or maybe not -- the logic in remote_start_remote seems not very trivial.

Right. :-/

> Basically, from the point of frontend we need a way to say that non-stop,
> and async, are desired, and to understand if that request is respected.
> Whether frontend sets 'non-stop' to 1 after 'target remote' and gets the
> error immediately, or sets it to 1 before target remote, and later queries
> if non-stop is actually enabled, is not very important. However, the
> behaviour of non-stop and of various ways to enable async should be
> consistent, I think.
>
> That is, the options are:
>
> 1. We do
>
> set non-stop 1
> set async 1
> target remote xxx
>
> and if the target does not support either non-stop, or async, we get error.
>
> 2. We do:
>
> set non-stop 1
> set async 1
> target remote xxx
>
> and if the target does not support either non-stop or async, we'll operate
> in all-stop, or sync more, respectively. There will be some way to check if
> we're really in non-stop, or async, mode.
>
> 3. We do:
>
> target remote xxxx
> set non-stop 1
> set async 1
>
> and then if non-stop or async is not supported, we get an error from the
> "set" command.

"set async 1" should just not exist (that's why it's a maintainance
commands today), so let's imagine it's not needed.

> For (3), the question is what to do if we send another "target XXX"
> command. Should we reset both variables, or should we do either (1) or (2).

> For (1) I don't like the hard error -- if the frontend really demands
> non-stop mode, it can always bark itself. So, I think (2) is best. OTOH,
> it's not how non-stop mode works now -- remote will error out if non stop
> is not supported by the stub, so we'd have to split non_stop into
> non_stop_requested and non_stop_actually_enabled, which is mechanical, but
> big change. What do you think is best here?

It's not a big change if we leave the non_stop global to mean that we're
in non_stop, and come up with a new non_stop_willingness global.

(2) is fine with me. It means that both linux-nat and remote
will have to set the non_stop global themselves, after checking the
non_stop_willingness global.

The core code that checks for non_stop always checks it when there's
already execution (e.g., interrupt and continue commands), unlike
asyncness, which is checked before creating an inferior in run
and attach, so it looks safe enough.

We'd then in the future make the non_stop inferior control global a
per-target property, or perhaps even per-inferior, but for now,
there's no harm in leaving it a global.

While we're on to it, perhaps we should rename the
command to:

set execution-mode "all-stop", "non-stop".

"all-stop"
prefer all-stop, but if the target doesn't support it, fine,
fall-back to what the target wants.
"non-stop"
prefer non-stop, but if the target doesn't support it, fine,
fall-back to what the target wants.

?

We leaves some slack to add new modes like this, which would
combine (1) and (2):

set prefered-execution-mode
"all-stop"
prefer all-stop, but if the target doesn't support it, fine.
"non-stop"
prefer non-stop, but if the target doesn't support it, fine.
"force-all-stop"
require all-stop, fail if the target refuses it.
"force-non-stop"
require all-stop, fail if the target refuses it.

?

In remote_open_1, the initial connection setup would change to
something similar to:

if (!rs->non_stop_aware)
{
if (prefered_execution_mode == FORCE_NON_STOP)
error ("boo!, target does not support non-stop");
non_stop = 0;
}
else
{
if (prefered_execution_mode == PREFER_NON_STOP)
{
putpkt ("QNonStop:0");
getpkt (&rs->buf, &rs->buf_size, 0);
if (strcmp (rs->buf, "OK") == 0)
non_stop = 1;
}
else if (prefered_execution_mode == PREFER_ALL_STOP)
{
putpkt ("QNonStop:0");
getpkt (&rs->buf, &rs->buf_size, 0);
if (strcmp (rs->buf, "OK") != 0)
non_stop = 1;
}
else if (prefered_execution_mode == FORCE_NON_STOP)
{
putpkt ("QNonStop:1");
getpkt (&rs->buf, &rs->buf_size, 0);
if (strcmp (rs->buf, "OK") != 0)
error ("boo!, target refused non-stop");
non_stop = 1;
}
else if (prefered_execution_mode == FORCE_ALL_STOP)
{
putpkt ("QNonStop:0");
getpkt (&rs->buf, &rs->buf_size, 0);
if (strcmp (rs->buf, "OK") != 0)
error ("boo!, target refused all-stop");
non_stop = 0;
}
}

If you want to check the current execution mode, you'd obviously
then read from the non_stop global (or whatever we rename it to).

This still leaves making targets other than linux and remote
refuse the FORCE_NON_STOP setting, but it doesn't sound as bad
if we fail to do that. Note that I'm just suggesting the FORCE_*
variants as a possible future direction, if it turns out required.
We may or not do it now, it's fine with me either way.

BTW, what is it that currently makes the frontend want to check if
non-stop has been activated? If it possible to remove that need,
other than for informational purposes?

> > Also, if we set non-stop and it enables async + breakpoints-always-in,
> > plus whatnot, and then the target refuses it, do we get to revert the
> > async,breakpoints always-in,whatnot settings?
>
> Well, I now think individual toggles are better -- with non-stop mode
> checking if async and breakpoints-always-inserted are on. This way, if we
> can't enable non-stop, the frontend is in control of whether the others two
> should still be enabled.

Re: always-inserted, make it a three-state?

- follow all/non-stop mode (default)
- on
- off

--
Pedro Alves