Multiprocess GDB, formal spec

Stan Shebs
2008-08-13T22:16:52Z

[-- Attachment #1: Type: text/plain, Size: 593 bytes --]

The following writeup is a more formal specification for multiprocess
GDB. It incorporates feedback from recent discussion, the results of my
experimentation with a prototype, and bits from the HPD draft standard.
Although there is a lot here, I wanted to lay out some longer-term
direction so as to clarify how the immediate work fits into the big
picture - the last section delimits what the first version will actually
do, which is not much more than what I was able to get working in a
couple weeks of prototyping (read: we have reason to believe it's
implementable :-) ).

Stan

[-- Attachment #2: mpgdb-spec --]
[-- Type: text/plain, Size: 10953 bytes --]

This is a behavioral specification for multiprocess/multiprogram
GDB. This specification is phrased in terms of user-visible behavior,
and generally organized according to the format of the GDB manual.

There is a technical distinction to be made between the term
"multiprogram" and "multiprocess". Most precisely, "multiprogram" or
"multiexec" refers to the ability to work with several different
executables at the same time within a debugging session. (Currently,
GDB can only handle one at a time; a command bringing in an
executable, such as "file", causes the previous one to be removed.)
Conversely, the term "multiprocess" is appropriate when GDB has
several inferiors, which may or may not be associated with the same
executable. However, since the two are being implemented together, the
distinction will not be important to users.

This spec borrows liberally from the HPD draft standard.

Definitions

Exec: Short for executable program, which is defined as a file that
contains a program which may be run independently of other programs.

Program: Synonym for exec. (Informally, "program" is preferable for
user documentation, while "exec" is preferable for GDB internals
documentation.)

Inferior: A GDB object representing a futurely-, currently- or
formerly-running program. There must be an inferior for each execution
of each program. (Informally, an inferior corresponds to a process or
corefile.)

Address space: A GDB object providing an interpretation of a
CORE_ADDR. Execs and inferiors each have at least one address space,
and may have several, with contents distinguished in a target-specific
way. Multiple execs and inferiors may share an address space.

Thread: A single locus of control within an inferior.

Inferior/thread set: A collection of inferiors and/or threads,
abbreviated "itset".

Generalities

Basic multiprogram and multiprocess support in GDB will be
automatically available in every version of GDB; there will be no
special configuration flags or compiletime options. Support for
simultaneous control of multiple inferiors will typically require
target-specific additions, and so some targets may not include these
additions; GDB will warn but do nothing else if the user attempts to
run more than one inferior at a time on these targets.

GDB's behavior in the case of one program and one inferior will be the
same as formerly, with the possible exception of some rarely-seen edge
cases.

* Inferiors and inferior sets

An inferior object is a representation of a single program run. While
conceptually similar to a Unix process, it is more general; an
inferior may be created before a program starts running, and it may
continue to exist after the program exits.

Running or attaching to a program creates an inferior if one does not
exist for the program already. The default name of the inferior
depends on the target, but is typically a number corresponding to
process id.

The syntax for symbols and source lines is extended to allow reference
to specific inferiors. An inferior-specific symbol reference is
'#<inf>#<symbol>', while a general source line reference has the form
'#<inf># :<line>'. If an inferior is not specified, GDB will
use a most logical inferior, such as the last one used, or one from
the current itset.

An inferior/thread set is a collection of inferiors and threads within
those inferiors. Itsets may enumerate their members explicitly, or be
determined dynamically; for instance, the itset named "all"
automatically includes all inferiors and all threads. Itsets may have
names.

The command-line syntax for inferior/thread sets is '[<spec>]', where
<spec> may take several forms.

[<name>]

Specifies the named itset <name>.

[<name>]

Specifies the inferior named <name> (which may be a number).

[<exec>]

Specifies the default inferior corresponding to the program named <exec>.

[<spec1>,<spec2>,<spec3>,...]

Specifies the union of the itsets specified by speci.

[<inf>.<thread>]

Specifies thread <thread> of inferior <inf>. Both <inf> and <thread>
may be '*', which specifies all of each.

[all]

Specifies all inferiors and all threads.

[TBD: Allow '[]' to be optional when it is unambiguous, as in focus command?]

focus <itset>

Sets the effect of subsequent commands to apply only to the inferiors
and threads in the given itset. This set is known as the "current" itset.

It will be possible to create inferiors manually. This will be useful
to set up complicated runs involving multiple instances of execs.

add-inferior <exec> [-copies <n>] [-name <name>]

Creates <n> (default 1) inferiors, all associated with the exec <exec>. The
inferiors will be numbered consecutively, with <name> as a common
prefix if specified.

remove-inferior <itset>

Deletes the inferiors included in <itset>. Autogenerated inferiors,
such as for execs, cannot be removed manually, but will go away when
the associated exec or other object is removed.

name-inferior <oldname> <newname>

Change the inferior named <oldname> to have the name <newname>.

info inferiors

Lists all inferiors in existence.

<itset> <cmd> <args> ...

Apply <cmd> <args> to everything in <itset>.

* Invoking GDB

GDB will allow multiple programs to be specified on the command line.
The basic form will be

gdb prog1 prog2 prog3 ...

If progi is recognized as a core file, then GDB will take it as a core
file corresponding to the most recently specified executable; it will
be an error if the previous argument is not an executable. Similarly,
if progi is a decimal number, GDB will interpret it as a process id,
corresponding to the last executable specified.

For instance,

gdb prog1 core1 prog2 core2

sets up to debug two programs prog1 and prog2, each with a
corresponding core file. Conversely,

gdb prog1 prog2 core1 core2

sets up to debug prog1 and two crashes of prog2, each with its own
core file.

For the sake of compatibility, the options -exec, -symbols, and -core
will clear the list of files already seen on the command line, and
replace them with the single file that is supplied with the option.
(This is so that "gdb -exec foo -exec bar" continues to work as
before.)

* Running Programs under GDB

The run command will run all the execs in the current itset. The
arguments to run will be passed to all execs; if no arguments are
supplied, then the arguments will be those associated with the exec's
inferior; either those set manually with "set args", or the same
arguments as used in the previous run.

attach <pid1> ...

Attaches to each process listed, and creates an inferior named after the pid.

detach [<itset>]

Detaches from each process mentioned in the optional <itset>. If
<itset> is omitted, GDB will detach from all process in the current
itset.

kill [<itset>]

Kills each process included in the optional <itset>. If <itset> is
omitted, GDB will attempt to kill every process in the current itset.

set args <arg> ...

Set the list of arguments to be used the next time any of the
inferiors in the current itset starts.

set environment <arg> ...

Similarly, for the environment.

set follow-fork-mode both

On targets that support process forking, lets the developer choose to
include both parent and child of a fork as processes being debugged.

set follow_exec true

On targets that support process exec'ing, lets the developer debug
processes created via exec/execl.

* Stopping and Continuing

Breakpoints, watchpoints, etc, are intrinsically global; any given
breakpoint may apply to a number of locations in each of several
executables. For instance, "break main" can cause every program under
GDB's control to stop soon after it starts; to break in only some executables,
the syntax "break #<inf>#main" would be necessary.

[TBD: have a way to delete "locations" from a breakpoint? too complicated?]

By default, the break and watch commands only associates a breakpoint
with members of the current itset.

Step only affects a single inferior, while continue may cause one or
all inferiors to resume execution. When one of the inferiors/threads
stops, GDB sets the current itset to consist of just the inferior and
thread that actually stopped. The user is free to change the focus
thereafter.

info program

Displays the status of each inferior currently in existence, including
whether it is stopped and why.

* Examining the Stack

By default, the backtrace and frame commands apply only to the current
thread in the current itset.

[TBD: Extend frame command syntax to #<inf>#<n> ? ]

* Examining Source Files

By default, an argument to the list command is interpreted as
referring to the first exec found in the current itset. An argument
may be prefixed with the '#' syntax designating a particular inferior.

* Examining Data

By default, the expression given to a print command is evaluated
relative to each member of the current itset. If there are multiple
threads and/or inferiors, each distinct value is printed separately,
prefixed by an itset spec showing which threads and/or inferiors
yielded that value.

* GDB Files

file <file> ...
exec-file <exec-file> ...
symbol-file <symbol-file> ...

Replace all files/exec files/symbol files with the given file(s).

add-file <file> ...

Adds <file> arguments to the list of executables and to the list of symbol files.

remove-file <fileids>

Removes <file> from the list of executables and from the list of symbol files.

info files

Lists all the execs that are being debugged.

add-exec-file <exec-file> ...

Adds <exec-file> to the list of executables being debugged.

remove-exec-file <execids>

Removes <exec-file> from the list of executables being debugged.

* Specifying a Debugging Target

Targets will need internal changes in order to support multiple inferiors,
but they need not change in any user-visible way.

The remote protocol will optionally send and receive id's identifying
the inferior to which each packet applies. Packets not identifying an
inferior will be assumed to refer to the current itset; if the current
itset contains more than one inferior, then they will be assumed to be
sharing the same address space.

* The GDB/MI Interface

[TBD]

** Planned limitations of the first version

The proposed set of extensions is a considerable amount of work, too
much to be done all at once. This section suggests a set of
limitations on the general capability that still yield a usable
multiprocess debugger.

The itset prefix to commands is not implemented.

Definition of named itsets is not supported.

The focus command only allows sets consisting of a single exec, and
focus in general is only on one inferior.

The attach command takes only one pid. The detach and kill commands take no arguments.

All inferiors must use the same target stack. (All remote, all native, etc)

The "both" follow-fork-mode and the follow-exec options are not available.

The file etc commands do not take multiple arguments.

The MI interface is not supported.