Q: utrace && ptrace_check_attach()

Oleg Nesterov oleg at redhat.com
Tue Jul 28 00:36:54 UTC 2009


On 07/27, Roland McGrath wrote:
>
> No, it can't.  That's what "get the bookkeeping right" means.
> It the debugger uses UTRACE_RESUME et al, then that thread moves
> from TASK_TRACED into TASK_STOPPED and still never runs.

Ah. In that case yes, we can make this all consistent.

But I am not sure I understand you right, please see below.

> > > The bookkeeping should ensure that when a TASK_TRACED thread was
> > > counted as stopped,
> >
> > But we can't know if it was already counted or not.
>
> Sure we can.  The group_stop_count is set by the stop-instigator while it
> holds siglock and checks every thread's ->state.  All transitions into or
> out of TASK_TRACED are done holding the siglock.  When you take siglock and
> see there is a stop in progress, then you know the thread's TASK_TRACED was
> counted as stopped in setting up that stop.

Yes, yes, sure.

But currently ptrace can wake up the tracee and then later it can be
ptrace_stop()'ed again, in this case we can decrement ->group_stop_count
twice for the same thread.


OK, forget about mt issues. Do you really mean PTRACE_CONT/etc must _not_
wake up SIGNAL_STOP_STOPPED tracee ? This would be nice perhaps, but this
means a serious user-visible change.

Or I misunderstood you?

> > And note that utrace_stop() doesn't set SIGNAL_STOP_STOPPED and doesn't
> > notify if ->group_stop_count becomes 0.
>
> We can fix this.

sure, this is minor.

> > Or do you think it is better to add tracehook_finish_stop() helper which is
> > called by do_signal_stop() to clear ->stopped ?
>
> Let's do it however makes the code taken all together come out cleanest.
> From what you said before, it sounds like tracehook_finish_stop() would
> help with that.

OK, I'll send the patch.

> > BTW, can't finish_utrace_stop() check utrace->stopped lockless?
>
> You tell me!

I think it can.

finish_utrace_stop() can't miss ->stopped if it was not cleared, it was
set by us. When finish_utrace_stop() takes utrace->lock to clear ->stopped
it can be already cleared by utrace_wakeup() but we don't care.

And, if ->stopped == F, nobody (utrace_do_stop() actually) can set it.
If this was possible we have a bug anyway.

Oleg.




More information about the utrace-devel mailing list