Q: who maintains the STOPPED/RUNNING state?
Oleg Nesterov
oleg@redhat.com
Wed Jul 21 10:20:00 GMT 2010
On 07/20, Frank Ch. Eigler wrote:
>
> Oleg Nesterov <oleg-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> writes:
>
> > [...]
> > Who maintains this state? gdb, server, both? To illustrate, suppose
> > that ugdb receives
> > $c <--- resumes the tracee
> > $g <--- asks general registers
> > What should ugdb do?
>
> Even if the protocol documentation theoretically permits this,
> if actual gdb does not send it, and actual gdbserver does not
> specifically handle it, you don't have to worry about it.
I'd like to know how can I check that gdb can't do this.
OK, it seems to be true, so I'll assume ugdb should return E01.
> > - reply E01 because it is not stopped?
> > - stop it, read the regs, reply ?
> > - stop, read the regs, reply, then resume it again ?
>
> I'm pretty sure that even if this packet is legitimate in this
> context, gdbserver will not stop the target thread just to pull out a
> sample of its registers. The values would become invalid the moment
> the thread resumed anyway.
Oh. Sure, but I used this scenario only to illustrate the question.
> > This is connected to another question. From gdb.info:
> > `H C THREAD-ID'
> > Set thread for subsequent operations (`m', `M', `g', `G', et.al.).
> > ...
> > What does this "Set" above actually mean? [...]
>
> (Whatever gdbserver uses it to mean.)
Nice. OK, unless I misread the (non-trivial) sources, gdbserver doesn't
stop the tracee. It merely sets general_thread, set_desired_inferior()
just sets current_inferior in this case.
> > To clarify, I am mostly asking about the protocol in general, not
> > about the current implementation in gdb.
>
> The abstract protocol is not precise enough or well-documented enough
> to answer these questions.
Thanks, I knew this from the very beginning ;)
> Reference to actual practice is usually
> required to implement the normal cases.
IOW, RTFS. Understand.
Yes, I tried to avoid the questions. Until I hit the limitations and
bugs (threading).
As for '$g' in particular... I didn't verify this, but looking at the
sources I strongly believe gdbserver is buggy.
It doesn't check the state of the tracee at all. Usually this doesn't
matter, because (I think) gdb will never send '$g' unless the tracee is
stopped. And if it is stopped, registers should be already cached in
thread_info->regcache_data, gdbserver does fetch_inferior_registers()
in advance when the tracee stops, before gdb actually asks.
However, if gdb sends '$g' when the tracee is not stopped, or if
get_thread_regcache() races with SIGKILL we have the (minor) problems.
regsets_fetch_inferior_registers() will notice that ptrace() fails
and it will complain via perror(), but that is all. It will send the
wrong regcache->registers content to gdb instead of E01.
OK. To answer my question, I think that ugdb can assume that the tracee
must be always stopped by debugger. Unless gdb asks to stop it, of
course.
Oleg.
More information about the Archer
mailing list