On 08/27, Ananth N Mavinakayanahalli wrote:
>
> On Tue, Aug 25, 2009 at 06:52:44PM +0200, Oleg Nesterov wrote:
>
> ...
>
> >  void exit_ptrace(struct task_struct *tracer)
> >  {
> > -   struct task_struct *p, *n;
> > -   LIST_HEAD(ptrace_dead);
> > -
> > -   write_lock_irq(&tasklist_lock);
> > -   list_for_each_entry_safe(p, n, &tracer->ptraced, ptrace_entry) {
> > -           if (__ptrace_detach(tracer, p))
> > -                   list_add(&p->ptrace_entry, &ptrace_dead);
> > -   }
> > -   write_unlock_irq(&tasklist_lock);
> > +   for (;;) {
> > +           struct task_struct *tracee = NULL;
> >
> > -   BUG_ON(!list_empty(&tracer->ptraced));
> > +           read_lock(&tasklist_lock);
> > +           if (!list_empty(&tracer->ptraced)) {
> > +                   tracee = list_first_entry(&tracer->ptraced,
> > +                                   struct task_struct, ptrace_entry);
> > +                   get_task_struct(tracee);
> > +           }
> > +           read_unlock(&tasklist_lock);
> > +           if (!tracee)
> > +                   break;
>
> Can tracee be NULL? If so, get_task_struct() shouldn't be called
> unconditionally above.

tracee == NULL when list_empty(->ptraced) == T. get_task_struct()
is called when we know we do have tracees,

        if (!list_empty()) {
                tracee = list_first_entry();
                get_task_struct(tracee);
        }

in that case tracee != NULL

Oleg.

Reply via email to