> I don't understand why this is better than just changing ->ops. Except,
> yes, I agree with above.

Sure, if you think about the innards they amount to about the same thing.
After PTRACE_DETACH, there is one engine attached and it uses the special
ops vector.  They are really just different ways to convince oneself that
there are no problematic races.  To change ->ops we have to convince
ourselves from scratch (which indeed perhaps is not all that hard).

> Adding another engine during detach adds more complexity, UTRACE_ATTACH_CREATE
> can fail, we should create the new context for new_engine->data...

It can only fail in pathological OOM situations (I think).  There it's
probably fine for PTRACE_DETACH to do something strange like yield and
return -ERESTARTNOINTR.

I'm not sure it needs any context structure.  It could just store the
signal number with engine->data=(void*)(unsigned long)signr (or just still
use someplace else like task->exit_code).

> But OK. Let's discuss this later. 

Agreed.

> At least we both agree ptrace_attach()
> should not try to re-use the old engine, and detach should use a special
> ops vector (with old or new engine). This makes me feel a bit better.

I think all three are plausible options.  We'll just have to see what seems
simplest and cleanest to cover all the corners (i.e. attach/detach races
and such) affected by this choice.

> Can't understand... Just in case, I'll explain which race I meant.
> 
> Suppose the freshly forked child should be ptraced. In that case
> ptrace_init_task(child) does ptrace_link() under write_lock(tasklist).

Clearly this is not part of any clean implementation in the long run.  In
any pure utrace-based implementation, or IMHO even any one with only as
much kludgery as ptrace semantics really demand (i.e. wait interference),
all related bookkeeping would be driven from ptrace's report_clone hook.


Thanks,
Roland

Reply via email to