lkml.org 
[lkml]   [2011]   [Jun]   [2]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    Date
    From
    SubjectRe: [PATCH 17/17] ptrace: implement PTRACE_LISTEN
    On 05/30, Tejun Heo wrote:
    >
    > This allows ptracer to monitor group stop state without running tracee
    > - use INTERRUPT to put tracee into STOP trap, issue LISTEN and then
    > wait(2) to wait for the next group stop event. When it happens,
    > PTRACE_GETSIGINFO provides information to determine the current state.

    Great. Just a couple of questions,

    > --- a/kernel/exit.c
    > +++ b/kernel/exit.c
    > @@ -1416,7 +1416,7 @@ static int wait_task_stopped(struct wait_opts *wo,
    > spin_lock_irq(&p->sighand->siglock);
    >
    > p_code = task_stopped_code(p, ptrace);
    > - if (unlikely(!p_code))
    > + if (unlikely(!p_code) || p->jobctl & JOBCTL_LISTENING)
    > goto unlock_sig;

    Up to you, but perhaps this JOBCTL_LISTENING check should go into
    task_stopped_code() ? Or do you think we can't check it without
    siglock?

    > + case PTRACE_LISTEN:
    > + /*
    > + * Listen for events. Tracee must be in STOP. It's not
    > + * resumed per-se but is not considered to be in TRACED by
    > + * wait(2) or ptrace(2). If an async event (e.g. group
    > + * stop state change) happens, tracee will enter STOP trap
    > + * again. Alternatively, ptracer can issue INTERRUPT to
    > + * finish listening and re-trap tracee into STOP.
    > + */
    > + if (unlikely(!seized || !lock_task_sighand(child, &flags)))
    > + break;
    > +
    > + si = child->last_siginfo;
    > + if (unlikely(!si || si->si_code != PTRACE_STOP_SI_CODE))
    > + break;
    > +
    > + child->jobctl |= JOBCTL_LISTENING;
    > +
    > + /*
    > + * If NOTIFY is set, it means event happened between start
    > + * of this trap and now. Trigger re-trap immediately.
    > + */
    > + if (child->jobctl & JOBCTL_TRAP_NOTIFY)
    > + signal_wake_up(child, true);

    Again, I won't insist if you prefer signal_wake_up(), but afaics
    wake_up_state(__TASK_TRACED) should be enough.

    > @@ -838,7 +840,7 @@ static void ptrace_trap_notify(struct task_struct *t)
    > assert_spin_locked(&t->sighand->siglock);
    >
    > task_set_jobctl_pending(t, JOBCTL_TRAP_NOTIFY);
    > - signal_wake_up(t, 0);
    > + signal_wake_up(t, t->jobctl & JOBCTL_LISTENING);
    > }

    OK. The only thing I can't understand is why prepare_signal(SIGCONT)
    calls ptrace_trap_notify() unconditionally. How about

    if (likely(!(t->ptrace & PT_SEIZED)))
    wake_up_state(t, __TASK_STOPPED);
    - else
    + else if (why)
    ptrace_trap_notify(t);

    ?

    Oleg.



    \
     
     \ /
      Last update: 2011-06-02 19:37    [W:0.024 / U:122.532 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site