ptrace: reintroduce __ptrace_detach() as a callee of ptrace_exit()
No functional changes, preparation for the next patch. Move the "should we release this child" logic into the separate handler, __ptrace_detach(). Signed-off-by: Oleg Nesterov <oleg@redhat.com> Cc: Jerome Marchand <jmarchan@redhat.com> Cc: Roland McGrath <roland@redhat.com> Cc: Denys Vlasenko <dvlasenk@redhat.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
Родитель
6d69cb87f0
Коммит
b1b4c6799f
|
@ -744,6 +744,38 @@ static int ignoring_children(struct sighand_struct *sigh)
|
|||
return ret;
|
||||
}
|
||||
|
||||
/* Returns nonzero if the tracee should be released. */
|
||||
int __ptrace_detach(struct task_struct *tracer, struct task_struct *p)
|
||||
{
|
||||
__ptrace_unlink(p);
|
||||
|
||||
if (p->exit_state != EXIT_ZOMBIE)
|
||||
return 0;
|
||||
/*
|
||||
* If it's a zombie, our attachedness prevented normal
|
||||
* parent notification or self-reaping. Do notification
|
||||
* now if it would have happened earlier. If it should
|
||||
* reap itself we return true.
|
||||
*
|
||||
* If it's our own child, there is no notification to do.
|
||||
* But if our normal children self-reap, then this child
|
||||
* was prevented by ptrace and we must reap it now.
|
||||
*/
|
||||
if (!task_detached(p) && thread_group_empty(p)) {
|
||||
if (!same_thread_group(p->real_parent, tracer))
|
||||
do_notify_parent(p, p->exit_signal);
|
||||
else if (ignoring_children(tracer->sighand))
|
||||
p->exit_signal = -1;
|
||||
}
|
||||
|
||||
if (!task_detached(p))
|
||||
return 0;
|
||||
|
||||
/* Mark it as in the process of being reaped. */
|
||||
p->exit_state = EXIT_DEAD;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Detach all tasks we were using ptrace on.
|
||||
* Any that need to be release_task'd are put on the @dead list.
|
||||
|
@ -755,36 +787,8 @@ static void ptrace_exit(struct task_struct *parent, struct list_head *dead)
|
|||
struct task_struct *p, *n;
|
||||
|
||||
list_for_each_entry_safe(p, n, &parent->ptraced, ptrace_entry) {
|
||||
__ptrace_unlink(p);
|
||||
|
||||
if (p->exit_state != EXIT_ZOMBIE)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* If it's a zombie, our attachedness prevented normal
|
||||
* parent notification or self-reaping. Do notification
|
||||
* now if it would have happened earlier. If it should
|
||||
* reap itself, add it to the @dead list. We can't call
|
||||
* release_task() here because we already hold tasklist_lock.
|
||||
*
|
||||
* If it's our own child, there is no notification to do.
|
||||
* But if our normal children self-reap, then this child
|
||||
* was prevented by ptrace and we must reap it now.
|
||||
*/
|
||||
if (!task_detached(p) && thread_group_empty(p)) {
|
||||
if (!same_thread_group(p->real_parent, parent))
|
||||
do_notify_parent(p, p->exit_signal);
|
||||
else if (ignoring_children(parent->sighand))
|
||||
p->exit_signal = -1;
|
||||
}
|
||||
|
||||
if (task_detached(p)) {
|
||||
/*
|
||||
* Mark it as in the process of being reaped.
|
||||
*/
|
||||
p->exit_state = EXIT_DEAD;
|
||||
if (__ptrace_detach(parent, p))
|
||||
list_add(&p->ptrace_entry, dead);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче