On 04/16, Roland McGrath wrote:
>
> > OK. For the moment, please forget about these changes. Let's recall
> > do_wait() has the ancient bug. wait_task_zombie() sets EXIT_DEAD
> > unconditionally, then drops tasklist. If we are not the real_parent
> > and the child was traced, we may restore >exit_state = EXIT_ZOMBIE
> > later. But, if the ->real_parent calls do_wait() in between, it can
> > see the child in EXIT_DEAD state and return -ECHLD.
>
> Really?  Won't that do_wait hit (wait_consider_task):
>
>       if (likely(!ptrace) && unlikely(p->ptrace)) {

Hmm, yes, its not that simple. Let me try again.

Two threads T1 and T2, and some process X (not the child of T1/T2).

T1 ptraces X.

X exits and becomes zombie.

T2 calls do_wait(WEXITED) and then wait_task_zombie(), it sets EXIT_DEAD
and drops tasklist.

T1 exits, calls exit_ptrace(). __ptrace_detach() does __ptrace_unlink()
and nothing more. From now X->ptrace == 0.

X->real_parent calls do_wait() and gets -ECHLD, because X is EXIT_DEAD
and not traced.


Of course, we can add the really nasty hacks to __ptrace_unlink() path,
but I think we should never set EXIT_DEAD unless we know for sure the
child will be released.

> > (and we have other minor problems with EXIT_DEAD tasks on ->children).
>
> Which?

Minor, but note the comment in find_new_reaper() about EXIT_DEAD tasks.
I thought I can give more arguments against EXIT_DEAD task on ->children,
but either I forgot, or they don't really exist ;)

Anyway. I think it would be more cleaner if, everytime we set EXIT_DEAD,
we also remove the task from list. The only problem is do_wait(), we
need write_lock(tasklist) for this, and yes, write_lock() is not very
nice. But as I said, this all is minor.

> (We can make this a separate thread if it's not really apropos just
> to ptrace.)

Yes, I think it would be better to keep emails small. Change the subject.

Oleg.

Reply via email to