On 10/29, Roland McGrath wrote:
>
> >     void utrace_finish_jctl(void)
> >     {
> >             struct utrace *utrace = task_utrace_struct(current);
> >             /*
> >              * While in TASK_STOPPED, we can be considered safely stopped by
> >              * utrace_do_stop(). Make sure we can do nothing until the 
> > tracer
> >              * drops utrace->lock
> >              */
> >             if (unlikely(__fatal_signal_pending()))
> >                     spin_unlock_wait(utrace->lock);
> >     }
> >
> > and utrace_stop() should do the same.
>
> I see.  The comments should be more clear that SIGKILL breaking
> TASK_TRACED is the only way this can arise.  In the jctl case, that is
> in particular after utrace_do_stop() changed TASK_STOPPED into TASK_TRACED.

Agreed.

> So today ->stopped really does still mean one other thing.  It means
> that it's either still in TASK_TRACED or is just waking up for SIGKILL.
>
> I think we've discussed the related stuff before.  A contrary approach
> would be to ensure that in the SIGKILL-breaks-UTRACE_STOP case we never
> make any more normal reports at all before utrace_report_death.

Yes, I agree.

> I was attracted by this until I started going through it.
> It's all good until you consider report_clone.  If a SIGKILL is pending
> when you get to utrace_report_clone(), the clone has already happened.
> If you skip that callback, the engine doesn't find out about the new
> child, and that matters if it's not a CLONE_THREAD.

another nasty case is report_exit(). Even if we fix the discussed problems
with explicit/implicit SIGKILL's. We shouldn't afaics skip this report if
the tracee was killed by execing sub-thread.

Both can be fixed if we add spin_unlock_wait() before REPORT(). But imho
it would be safer if we start with spin_unlock_wait() in utrace_stop(),
perhaps there is something else to consider.

Oleg.

Reply via email to