This is the mail archive of the archer@sourceware.org mailing list for the Archer 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: plan for python inferiors, threads, and events


On Friday 12 December 2008 19:11:25, Tom Tromey wrote:
> * It ought to keep working once gdb moves to multi-process.

In head, you have inferior objects to represent process inferiors and
core inferiors, but no such thing for representing executable program
inferiors.  This means that when you start GDB and use "file" to load
symbols, there's no inferior object yet, on which to issue "run".  This
is a very fundamental difference.  Not sure if you can come up with
something that won't change later.

> class gdb.Inferior
> 
>   Represents a single inferior.
> 
>   Some attributes:
> 
>   * pid.  The inferior pid.  It isn't clear how useful this is to
>     expose, given remote debugging and whatnot.

It would be nice to expose, to be able to easily pass that to
other tools or commands.

>   * threads.  A tuple holding all the currently existing threads of
>     this inferior.  A "live" inferior always has at least one thread.
>     When the threads change internally, the implementation will update
>     this tuple.

>   Maybe we need some events here?  "thread_started"?  Events to notify
>   changes in the overall inferior state?

You'll probably end up wanting all the same hooks/observers as an MI client
wants.  Notice that on the core side, a single resume/stop event/observer/method
doesn't necessarily apply to a single thread only.  It can apply to all threads
of all processes, or to all threads of a single-process as well.

And then there's itsets on the multi-process branch, but we
aren't doing much with them yet.

>   Some methods:
> 
>   * run.  Start the inferior.

Right...  If the current design in the multi-process branch sticks around,
executable programs are exposed as inferiors as well.  Then, you could
do my_executable_inferior.run();  I suppose we could
have my_another_already_running_process_inferior.run() work as well, by making
it look up the executable of the process inferior and runs a new copy of that.
Speaking in core side terms, keep in mind that the inferior object instance
that you are executing "run" on, wouldn't be the same instance that represents
the process that is spawned by the OS.  This latter one is represented as
another new inferior, with its own inferior GDB id.
But, this is only on the MP branch; on head, executable file inferiors aren't
represented yet, so there's no inferior to execute "run" on, until
you run one --- one could claim that Target.run({exec, args, ...}) would be
a more appropriate interface.

Please also consider:

 - 'target remote', and,
 -  the base multi-process/single-exec support that's already in GDB head,
    currently only supported in the remote target.  When you open a
    connection to the remote side, you "notice" a new inferior, or
    several new inferiors already under the stubs control.

> 
> class gdb.InferiorThread
> 
>   This represents a single inferior thread.
>   I didn't name this "Thread" since there is already a commonly-used
>   Python class of that name... or maybe we should use Thread and just
>   let packages work their magic?

I don't know python, but, if I did, I'd choose the latter.  :-)

>   Some attributes:

>   * stop_event.  An event which is fired when a thread stops.  The
>     stop reason (struct bpstats) would be passed as an argument.  See
>     below for info about events.

Right, this is messy business.  I guess you're talking about stop
events similarly to how MI sees stops.  As in, not interested
in internal events like each single-step when doing a "step" operation.
The bpstat doesn't represent all the possible stop reasons.
See print_stop_reason and normal_stop.  This is something that IMO
could be cleaner in the core side too, not just abstracted in the
scripting layer.  async_stop_reason, and the normal_stop observer may
be close to what you want here.

> 
>     It isn't totally clear that this is the correct abstraction.  In
>     some modes (non-stop), I think it is.  In all-stop, it seems less
>     clear.

A single stop event can say: "thread 1 hit breakpoint, all threads stopped",
whereas in non-stop it can say, "thread 1 hit breakpoint, threads 1 stopped".
A process exit is also a kind of stop event, not associated with a particular
thread.  So, in sum, a stop event isn't necessarily attached to a
single thread.
One could say that it would be nice to be able to query a thread
about why is it that it is stopped, but that isn't currently possible.  GDB
discards part of the interesting info while/after handling an event.

>   * continue_event.  Fired with no arguments when the thread starts
>     running again.

See mi/mi-interp.c:mi_on_resume.  This has similar considerations
to stop events, in that a single core event can tell you that "all"
threads have been made runnable at once.  Not sure if you'd want
to de-multiply that on the python interface.

-- 
Pedro Alves


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