Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 139689
b: refs/heads/master
c: b1b4c67
h: refs/heads/master
i:
  139687: 0488aae
v: v3
  • Loading branch information
Oleg Nesterov authored and Linus Torvalds committed Apr 3, 2009
1 parent 9de8d7e commit d0f650d
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 30 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 6d69cb87f05eef3b02370b2f7bae608ad2301a00
refs/heads/master: b1b4c6799fb59e710454bfe0ab477cb8523a8667
62 changes: 33 additions & 29 deletions trunk/kernel/exit.c
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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);
}
}
}

Expand Down

0 comments on commit d0f650d

Please sign in to comment.