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.