Adjust MI non-stop/MI3 spec
Vladimir Prus
vladimir@codesourcery.com
Mon May 5 08:33:00 GMT 2008
Attached is the current version of MI non-stop/MI3 spec, in case
anybody's interested. Nothing drastic changed, except some changes
were moved to MI3, and the --thread option is no longer required
in MI2 non-stop mode.
- Volodya
-------------- next part --------------
MI3/non-stop MI spec
==================
Legend:
(*) Behaviour to be implemented in MI3
-> Todo items
General clarifications
----------------------
(*) It is not longer required that async output record, or result
record, is followed by a prompt. Instead, prompt is used to indicate
that gdb is ready to accept next command. Each MI command results in
either ^done or ^error. The ^done response means that the previous
command is successfully executed. For commands that run the target,
^done is output immediately when the target was successfully resumed.
Any further change in the state of the target is reported via async
output records. The prompt will be printed either immediately after
^done, if GDB can accept commands while target is running, or when
the target stops.
Notes: A frontend can send a command without waiting for
the prompt, and it will be eventually processed. However, if gdb
has not printed a prompt after the previous command yet, it means
that it might take a lot time until the next command will be executed.
The frontend may use the lack of prompt to disable some commands, or
to show "waiting for previous command to finish" indicator.
New notifications
-----------------
1. The *running notification is introduced, in the form:
*running,thread-id="xxx"
It's emitted whenever a thread is resumed. "xxx" can be all if all
threads are resumed.
2. The *stopped notification will get a new field, 'stopped-threads':
*stopped,thread-id="xxx",stopped-threads=[...]
Here, the thread-id field indicates the thread which caused the stop,
and the stopped-threads lists all threads that were stopped as result.
Typically, those are all threads in the program for all-stop mode
and the same thread as in thread-id for non-stop mode.
The value of the stopped-threads field can be either list of thread ids,
or a string "all".
Explicit thread specification
-----------------------------
All MI commands accept a new option --thread that indicates which
thread the command should operate on. Using an MI command with
this option does not change GDB's externally visible notion of the
current thread, nor does it emit any "thread changed" notification.
The --thread option essentially allows the frontend to examine any
thread it wants without making that thread current and without depending
on GDB's current thread. Lacking this, a frontend wishing to examine
non-current thread should emit -thread-select, perform the operation
and the -thread-select back. This is both extra commands to send,
and it creates a window where the current thread as seen in GDB console
is not the one that is expected.
-> In fact, we probably should make thread selection, internally, not
to reset the frame to 0. Otherwise, frontend can nicely messup GDB
console.
(*) MI3 might make this option required.
Async/non-stop mode notes
-------------------------
The async mode basically means that gdb can process commands even while
the target is running. This mode is enabled whenever the target is
async-capable.
In async mode, there are two further distinctions:
- Should we allow an exec command while some other exec command
is already in progress?
- Should we stop all threads whenever an event is detected in one thread?
Those issues seem independent initially, so we might try to allow
two -exec-next at one time, and then stop all threads when any -exec-next
is finished. However, that will require user to explicitly resume the
-exec-next that is not yet finished, which does not seem very helpful --
it's not much better than sending two -exec-next sequentally.
Therefore, for now we shall have only two modes:
- "all-stop", when all threads are stopped if any thread stops,
and when only one exec command is allowed to be active at any given time,
- "non-stop", where individual threads are stopped, and several
exec commands can be active.
Except for what is said above "all-stop" and "non-stop" async modes are
identical.
Generally, most MI commands are allowed while a target is running, with the
following exceptions:
- An execution command that logically applies to a single thread
cannot be used if the thread is already running. Global -exec-continue is
OK, and will resume all threads that are not presently running. In all-stop
mode an execution command cannot be started if any thread is running.
- Some data access commands are also implicitly using a specific thread --
because they are using registers, or variables in specific thread/frame,
or because they have to call a function in the inferior. Such data access
commands are not allowed when the necessary thread is running. Wholesale
update operations like -var-update will plain ignore variable objects
that need now-running threads.
- The commands that grab global state of the target are allowed when
some threads are running. It should be understood that the result may
be inaccurate -- in particular, the memory content can change while
we read it, and the list of threads might not be updated until some
event from the target arrives. In addition, some targets might not
even allow reading memory while all threads are running -- so memory
access commands on such targets will require that at least one thread
is stopped.
To simplify things, if GDB is started in MI mode, no CLI command is allowed
while the target is running. The -interpreter-exec is allowed, but
is at user's risk.
Note: in cases when to implement a command, GDB requires that at least
one (or all) threads are stopped, and the command is issued when this
condition is not met, we have two choices -- issue an error, or briefly
stop the target, perform the operation, and resume. Clearly, doing
that in GDB (or even in the target) will be less intrusive then doing
that in frontend. However, it might be still too intrusive. For now,
we'll just emit error, should a real need arise, we can always implement
automatic interruption of the target.
MI non-stop command changes
---------------------------
When operating in non-stop mode, GDB does not automatically switch
the current thread to a thread that got some event. This is to avoid
annoying CLI users with switches to some other thread as he's doing
something with the current selected thread. This is also to avoid
changing the meaning of the commands already sent/queued by the frontend,
in case the frontend choose not to use the --thread option.
- Break commands. The primary limitation on breakpoint commands is
that it is not possible to insert or remove breakpoints from the
target if all threads of the target are running. Therefore, the
-break-insert, -break-watch, -break-delete, -break-enable and
-break-disable commands are not allowed unless at least one
thread is stopped.
The -break-info, -break-list, -break-after, -break-condition commands
are allowed.
The -break-catch and -break-commands commands are not presently
implemented and will not be implemented.
If -break-insert command specifies only line number, then it implicitly
depends on the filename of the current thread/frame. In non-stop mode,
the frontend is required to specify thread and frame explicitly.
- Program context commands. Those are not allowed after the program
has started execution.
- Thread commands. There are no limitations. Note that while
the -thread-select command can be used on a thread that is currently
running, very few of other commands will work on a running thread.
- Program execution. The -exec-next, -exec-step, -exec-finish,
-exec-until, -exec-return, -exec-step-instruction and
-exec-next-instruction always resume just the thread specified
with the --thread option, or the current thread. This is the same
as using "scheduler-locking on" in all-stop mode.
The -exec-continue will resume just the thread specified with the --thread
parameter, or the current thread. To resume all threads, one must
pass the --all option. If a specific
thread was resumed with -exec-continue, then should that thread create
another thread, that new thread won't be running. If case the entire
program was resumed, then new threads will be running as well.
- Stack commands. All are allowed. All require a thread parameter in
non-stop mode.
- Variable objects. The thread -var-create operands on must be stopped.
If a variable object makes use of any local variable, the object
becomes bound to the
thread where it was created. An attempt to manipulate an
individual variable obect when the thread it is bound to is not
stopped results in an error. As a special exception, -var-update will
ignore any variable object whose bound thread is not stopped.
A variable object's expression might involve a function call. If a
variable object is not bound to any thread, the function call will be
executed in any currently stopped thread.
-> Decide/check if we can create a global varobj when all threads
are running.
- Data manipulation. All commands are supported, except for
data-list-changed-registers, which is presently thread-unaware and seems
inferior to using variable objects anyway.
The -data-evaluate-expression and -data-list-register-values requires
that either the --thread or the --global option be provided.
- Symbol query commands. All are supported.
- File commands. The -file-exec-and-symbols and -file-exec-file cannot
be used when any thread is running. The -file-list-shared-libraries
can be used while inferior is running, but the results might be
invalidated immediately. Same for -file-list-symbol-files. Others
can be used without limitations.
On some targets it might not be possible to get the list of shared
libraries from the target while it is running. In such cases, GDB will
report an error.
- Target manipulation. The -target-disconnect can be used while threads
are running. Other (currently implemented) commands can only
be used before we have an executable.
- File transfer. Can be always used.
- Misc. Case-by-case, nothing interesting.
More information about the Gdb
mailing list