This is the mail archive of the gdb@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: MI non-stop interface details


Vladimir Prus wrote:
On Wednesday 30 April 2008 21:20:24 Pawel Piech wrote:
Vladimir Prus wrote:
Again -- exec-continue resuming just one thread will be a change in behaviour.
We can take two approaches:

1. The MI interface we've discussed for non-stop is essentially MI3 (and will
be used both in all-stop and non-stop mode). We're in position to change anything
we like, and are not bound by backward compatibility, or anything.

2. The MI interface for non-stop is MI2 + minimal set of changes. I think that
Pawel's opposition to the --thread idea indicates that he prefers this approach.
Then, we rather not change the behaviour of existing commands.

There are not many high-level warts in MI2/non-stop/async, so I'm willing
to go with (2).

- Volodya
First of all I really appreciate your effort to maintain backward compatibility. I know that it can seriously complicate the effort to add new features but I believe this effort pays off in quicker and more reliable adoption by the users (IDEs). However, there are two kinds of backward compatibility goals to consider:
1) Allowing old GDB clients to use the new, extended protocol.
2) Allow clients that use the extended protocol to easily work with old protocol versions. And by "easily", I mean that the client should be able to not have "if(non-stop) { use command a } else { use command b}" kind of logic scattered throughout its implementation.

Why do you have such a goal?
Adoption of new versions of GDB is gradual, so for clients support for old versions of GDB is very important.
Goal 1) is a little more obvious and it is being satisfied by having an explicit all-stop/non-stop switch which has to be set in order to enable the new protocol extensions. Goal 2) is somewhat more complicated and difficult to achieve but I think it is possible with a few adjustments to the current proposal. (Note that the second goal is actually not just about compatibility with older versions, it also has to do with using the latest version of GDB with targets that don't support.) non-stop mode.

As far as the protocol is concerned, I think the best way to think about the difference between non-stop and all-stop is that all-stop is a degenerate mode of non-stop where the all-stop mode has the limitation that resuming a single thread always has the side effect of resuming the entire process. The first step in allowing the client to deal with this difference is to add a field to the state change events which indicate what context has actually changed state. For this purpose I previously suggested adding a "container-ids" parameter to the *resumed and *stopped events. In the extended protocol, this parameter would tell the client whether the whole process was resumed or just a single thread, and it should be present in either non-stop or all-stop mode.

Currently, both *running and *stopped have "thread-id" field.
But your proposal doesn't add any fields to the events indicating whether the stopped event stops a single thread or the whole process. Even in non-stop mode alone this is important since commands can be issued to do both.
When working with older versions of GDB, this parameter would be absent, which would allow the client to deduce that the whole process was resumed.

The next problem to solve is the fact that non-stop needs an additional feature: explicitly resuming/stopping/stepping the entire process. That's right, if you think of all-stop as a degenerate mode, it's not controlling the individual threads that is new, but it is controlling of the entire process that needs to be added. One way to add this feature is to extend the run control commands to take a special parameter, i.e. -all/--thread-id="all", etc. The draw-back to this approach is that it would still require the client to have the "if (non-stop)..." kind of logic in its processing, because old versions of GDB would return an error if they saw this option.

And why is such conditional logic bad? I understand that adding 200 "if" to codebase is both tedious and indicates a high risk of missing 10 more places. I don't think that doing conditional behaviour if a few places is bad.

I think you answered your own question. Even a few conditional changes in every release add up quickly.
But there is a way around this (which I proposed before but which I didn't receive any response about): Designate thread "1" as the default container thread. I.e. sending "-exec-continue --thread-id="1"" would resume the entire process ("-thread-select 1" followed by "-exec-continue") would do the same. All other logic dealing with threads, -thread-list-ids, -thread-info, etc could still work as it does today, it would just return threads starting with id of "2". When working with old versions of GDB, thread 1 is always present, and since old versions of GDB implement all-stop mode only, the resume-all button in the IDE would still work as expected.

In order versions of GDB, thread 1 is not always present. In particular,
on Linux x86, single-threaded applications are reported as having no thread.
Even if that were not true, I'm reluctant to add magic numbers of the
namespace of thread ids.


I assume there must be implementation complications to this propsal, but as I've mentioned before, but I think it's worth considering as it would also allow GDB to easily extend the MI protocol to support multi-process debugging, where a new command:
"-list-container-ids" would return the thread-ids of processes, and "-list-thread-ids --thread-id="1"" would return threads within the given container.

I'll probably start designing multi-process extensions for MI this week,
and will look into these suggestions. Why are you trying to use same
namespace for process ids and thread ids?


- Volodya
I see no reason to create a separate name space and in fact adding another name space just requires more logic to maintain it. thread-id is just a handle that is obtained through well-documented commands, the MI clients are not likely to get confused by the fact that containers and threads are in the same namespace. Additionally, if GDB was ever to support more hierarchical systems: such as target->core->processes->threads, it will have to keep revising the protocol (in incompatibility inducing ways) to keep up. But I guess you'd have to believe that this is a real issue first.

Cheers,
Pawel


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]