utrace_wakeup:

        if (likely(task_is_stopped_or_traced(target))) {
                if (target->signal->flags & SIGNAL_STOP_STOPPED)
                        target->state = TASK_STOPPED;
                else
                        wake_up_state(target, __TASK_STOPPED | __TASK_TRACED);
        }

Let's forget about ptrace for the moment.

The code above means that utrace can't wake up the tracee if it was
group-stopped. This looks reasonable, but in that case I don't understand
what should we do if ->report_signal() returns UTRACE_SIGNAL_STOP. I mean,
the attached engine can stop the tracee but can't wake it up?

However, utrace_wakeup() is not right. It only checks SIGNAL_STOP_STOPPED,
but doesn't check ->group_stop_count. But, otoh, we need no checks here,
utrace_wakeup() can just do wake_up_state(__TASK_TRACED) and nothing more
(remember, I am ignoring ptrace issues).


but ptrace_resume() is different, it should wake up the tracee, that is
why it does:

                if (task_is_stopped(child)) {
                        spin_lock_irq(&child->sighand->siglock);
                        child->signal->flags &= ~SIGNAL_STOP_STOPPED;
                        spin_unlock_irq(&child->sighand->siglock);
                }

and this code is wrong again: what if check ->group_stop_count != 0?
In that case SIGNAL_STOP_STOPPED can be set later, when utrace_wakeup()
is called.


(note that we have more problems with utrace_report_jctl() playing
 with task->state/signal->flags, should be fixed by the cleanups
 discussed in another thread).

What can we do? I don't see any solution.

Oleg.

Reply via email to