> Agreed, this looks like a right change to me. In any case I think this makes
> the code more understandable and logical, and ->resume_action is much better
> than ->reports imho.

Ok.

> But, you seem to forget to fix other callers of utrace_stop(),

Yes, it was not a complete patch, just to get your feedback.  I'll commit a
more complete version.  It's still not really right for the vfork case, but
I want to avoid thinking about that for the moment.  (I've always intended
that eventually we would clean up the interaction with vfork-wait entirely
differently.)

> Can't we (well, partly) miss UTRACE_STOP request?
> 
> Two engines A and B. Say, utrace_report_exec() calls ->report_exec().
> 
> A returns UTRACE_STOP, B returns UTRACE_INTERRUPT.
> 
> ->resume_action = UTRACE_INTERRUPT, finish_report() sets ->interrupt = 1,
> utrace_report_exec() returns.
> 
> Now. We can't rely on utrace_resume()->finish_resume_report() which can
> notice the stop request and do utrace_stop() to actually stop. This is
> delayed until utrace_get_signal()->finish_resume_report(), and I am not
> sure this is what we really want:
> 
>       - minor, but it is possible that tracehook_notify_jctl() will
>         be called before tracehook_get_signal(). Not a real problem,
>         but shouldn't UTRACE_STOP mean "stop as soon as possible" ?

No.  It means "stop before this thread can newly cause any userland-visible
effects".  That means before:

        * executing a syscall (i.e. after report_syscall_entry)
        * dequeuing a signal
        * returning to user mode

If you used UTRACE_STOP and then get a report_jctl callback before
stopping, that means there was a group stop that was not initiated by this
thread.  The completion of the group stop is a userland-visible effect, but
that has already happened regardless, and was not caused by this thread.

>       - utrace_get_signal() can return without finish_resume_report()
>         if B->report_signal() (say) returns UTRACE_SIGNAL_DELIVER.
>
>         Yes, in this case A->report_signal() can return UTRACE_STOP
>         again, this means utrace_get_signal() returns with ->report = T.

That's how it's supposed to be.  Everybody gets another look after the
thread's state was changed by handler setup.

>         But another UTRACE_INTERRUPT can set ->interrupt, this can
>         "disable" ->report again, and so on.

I don't follow.  utrace_resume is guaranteed to be called.  If
UTRACE_INTERRUPT was used, then it punts because utrace_get_signal is
guaranteed to be called as soon as it returns.  Either way, everybody with
UTRACE_EVENT(QUIESCE) set gets another callback.

> In short: unless I missed something, it is hardly possible to predict when
> the tracee will actually stop, perhaps UTRACE_STOP needs more respect?

Sorry, I don't understand this comment at all.  The tracee will actually
stop before it would otherwise enter a syscall, dequeue a signal, or return
to user mode.  That is always the rule, end of story.  I can't see what it
is I am overlooking in the scenario that concerns you.


Thanks,
Roland

Reply via email to