> For example, wait_consider_task(). Even some tracehooks, say,
> tracehook_notify_death() need task_is_ptraced().

Not "some", just that one, right?  So these are all really the same one
thing: ptrace interfering with normal parent wait/SIGCHLD.

In previous iterations, we had tracehook_inhibit_wait for hiding this in
the tracehook layer.  Then I decided to drop that and wait to revisit it
until the final big ptrace clean-up.  And now here we are!

In the first utrace API, we had a NOREAP feature for this "cleanly" in the
utrace layer, so any engine could say it wanted to interfere like ptrace.
That was only there for ptrace and we really want nothing else new ever to
be able to interfere like that.  (An engine could delay death by using
UTRACE_STOP at exit-tracing, and can get reap notification to track what
the real parent does, but it can't hide death from the real parent or
prevent reaping once death is upon us.)  I'm still fairly confident that it
would not be a useful general feature to let anybody ever foul up the real
parent like ptrace does.  So bottom line, I think it is probably fine and
proper to have some manner of ptrace-only special-case for this.

For the core kernel code, I think it is probably right to reintroduce
tracehook_inhibit_wait.  do_wait_thread:

                if (!task_detached(p) && !tracehook_inhibit_wait(p)) {
                        int ret = wait_consider_task(wo, tsk, 0, p);

That keeps it simple and clean there.
The logic inside tracehook_{inhibit_wait,notify_death,notify_jctl}
will hide the actual implementation.

I'm inclined to avoid any more magic bits in utrace_flags,
because I expect those bits to become useful and precious later.
So I'd do:

        static inline bool tracehook_inhibit_wait(struct task_struct *task)
        {
                return task->utrace_flags && utrace_inhibit_wait(task);
        }

and then utrace_inhibit_wait can look at a bit we keep in struct utrace or
something like that.  I think we might be able to get away with unlocked
checks of that bit in wait, if we're sure that we'll do an extra
wake_up_parent after detach or whatnot.

OTOH, here's another idea.  I think it might be the case that after being
ptrace-attached and before any place that could matter (i.e. entering an
exit_state or TASK_STOPPED) the tracee will go through some ->report_*
callback to ptrace.  In synchronous callbacks, it can do current->flags|=
and then we could use a PF_* flag for this and keep the tracehook_inhibit_wait
check extremely cheap.


Thanks,
Roland

Reply via email to