On 10/12, Roland McGrath wrote:
>
> > No, the return calue from utrace_barrier() does not matter. And, if the
> > tracee is killed we don't care. The race is different.
>
> The utrace_barrier return value should cover exactly the case you describe,
> and that is the clean way to do it.  It will fail if the tracee is either
> dead or detached.

Thanks, I think you are right, and this should work.

But. This is connected to

        https://www.redhat.com/archives/utrace-devel/2009-October/msg00132.html

and I still think utrace_barrier() and finish_callback() pathes need more mb's.

This case is very similar to the previous pseudo-code. Suppose that
utrace_get_signal() calls ->report_signal() which returns UTRACE_DETACH
while the tracer does utrace_barrier().

Tracee, finish_callback() path:

        if (action == UTRACE_DETACH)
                engine->ops = utrace_detached_ops;

        utrace->reporting = NULL;

no barries, no utrace->lock() in between.

Tracer, utrace_barrier() under utrace->lock:

        if (engine->ops == utrace_detached_ops)
                return -EXXX;

        if (utrace->reporting != engine)
                return 0;

Afaics, this is racy and should be fixed in utrace level.

What do you think?

---

 kernel/ptrace.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

--- PU/kernel/ptrace.c~85_REUSE_RELY_ON_BARRIER 2009-10-13 14:01:43.000000000 
+0200
+++ PU/kernel/ptrace.c  2009-10-13 14:15:48.000000000 +0200
@@ -459,8 +459,8 @@ static int ptrace_attach_task(struct tas
                        /*
                         * Make sure we don't race with ptrace_report_signal()
                         */
-                       utrace_barrier(tracee, engine);
-                       if (engine->ops == &ptrace_utrace_ops)
+                       err = utrace_barrier(tracee, engine);
+                       if (!err)
                                goto finish;
                }
                utrace_engine_put(engine);

Reply via email to