utrace_control(,,UTRACE_SINGLESTEP)
Oleg Nesterov
oleg at redhat.com
Tue Oct 27 23:08:38 UTC 2009
On 10/27, Roland McGrath wrote:
>
> [I have no idea why you appended this to that message introducing patches
> that are not related to this at all. Please use separate threads for
> separate topics, and choose clearly apropos Subject: lines.]
OK.
> > I am thinking how can we fix utrace_control(SINGLESTEP). I don't
> > have good ideas so far. But, perhaps we can add
> > utrace->please_enable_single_step:1 ?
>
> If anything like this, it would be an enum utrace_resume_action field.
> Otherwise you are changing the API fundamentally.
Not sure I understand... This is like utrace->vfork_stop:1, it is
only visible to utrace code.
> > utrace_stop() and utrace_finish_jctl() can check this flag after wakeup
>
> What you mean here is an API where utrace_control's choice of resume_action
> takes effect without further callbacks when nothing else has requested any.
> As always, I want a discussion of the API semantics to be clear and
> separate from implementation details.
Yes. please see below.
> > Or, we can use ENGINE_SINGLESTEP, which probably makes more sense.
> > Like ENGINE_STOP, it lives both in engine->flags and ->utrace_flags.
>
> This takes us back to the old old utrace API where we had sticky state
> bits for the things that are now represented in utrace_resume_action.
> That is a very bad API choice IMHO, and its inherent unpleasantnesses
> are why we abandoned it before.
Agreed. I tried to think about ENGINE_SINGLESTEP more and came to the
same conclusion.
So. I am still not sure this is the best solution (in fact this doesn't
even look like a good solution to me), but afaics we can preserve the
current API and fix the problem if we add utrace->set_singlestep and
utrace->set_blockstep.
utrace_control()
case UTRACE_RESUME:
if (likely(reset)) {
user_disable_single_step(target);
utrace->set_singlestep = utrace->set_blockstep = 0;
}
break;
case UTRACE_SINGLESTEP:
if (likely(reset))
utrace->set_singlestep = true;
else
ret = -EAGAIN;
break;
void utrace_finish_stop(...)
{
if (!(utrace->stop || utrace->set_singlestep))
return;
set_singlestep = utrace->set_singlestep;
spin_lock(&utrace->lock);
utrace->stopped = trace->set_singlestep = false;
spin_unlock(&utrace->lock);
if (set_singlestep)
user_enable_single_step(current);
}
utrace_finish_jctl() and utrace_stop() should call this new helper
instead of "if (utrace->stopped) {}" code.
> > I no longer think utrace_control() should just turn SINGLESTEP into
> > REPORT silently.
>
> IMHO this characterization misrepresents what the API is today, and
> glosses over the real complexities that are why it is that way.
>
> There is no "silent" about it. If things are going on that affect what
> you asked for, then you get a callback to decide what you really want.
> The inability to react to other engines' effects this way was one of the
> major failings of the old "sticky action bits" API.
Yes I see. And I agree, the current behaviour of utrace_control(SINGLESTEP)
which ->set_blockstep hack tries to preserve is not very good.
As for ptrace. If utrace_control(SINGLESTEP) doesn't set TIF_SINGLESTEP,
then we need more (probably nasty) changes. report_quiesce/interrupt should
somehow figure out whether we need send_sigtrap() if ->resume == XXXSTEP.
So. What do you think we should do for V1 ?
Oleg.
More information about the utrace-devel
mailing list