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