Introduce the "utrace-friendly" ptrace_wake_up() and use it instead of
wake_up_process().

Kill ptrace_untrace(), detach should wake up the tracee correctly via
UTRACE_DETACH.

---

 kernel/ptrace.c |   47 ++++++++++++++++++++---------------------------
 1 file changed, 20 insertions(+), 27 deletions(-)

--- MINI/kernel/ptrace.c~5_WAKEUP       2009-08-25 17:54:50.000000000 +0200
+++ MINI/kernel/ptrace.c        2009-08-25 18:09:38.000000000 +0200
@@ -98,6 +98,25 @@ void xxx_ptrace_notify_stop(struct task_
        utrace_engine_put(engine);
 }
 
+static void ptrace_wake_up(struct task_struct *task)
+{
+       struct utrace_engine *engine;
+
+       engine = utrace_attach_task(task, UTRACE_ATTACH_MATCH_OPS,
+                                   &ptrace_utrace_ops, NULL);
+       if (unlikely(IS_ERR(engine)))
+               return;
+
+       if (task_is_stopped_or_traced(task)) {
+               spin_lock_irq(&task->sighand->siglock);
+               task->signal->flags &= ~SIGNAL_STOP_STOPPED;
+               spin_unlock_irq(&task->sighand->siglock);
+       }
+
+       utrace_control(task, engine, UTRACE_RESUME);
+       utrace_engine_put(engine);
+}
+
 /*
  * ptrace a task: make the debugger its new parent and
  * move it to the ptrace list.
@@ -112,30 +131,6 @@ void __ptrace_link(struct task_struct *c
 }
 
 /*
- * Turn a tracing stop into a normal stop now, since with no tracer there
- * would be no way to wake it up with SIGCONT or SIGKILL.  If there was a
- * signal sent that would resume the child, but didn't because it was in
- * TASK_TRACED, resume it now.
- * Requires that irqs be disabled.
- */
-static void ptrace_untrace(struct task_struct *child)
-{
-       spin_lock(&child->sighand->siglock);
-       if (task_is_traced(child)) {
-               /*
-                * If the group stop is completed or in progress,
-                * this thread was already counted as stopped.
-                */
-               if (child->signal->flags & SIGNAL_STOP_STOPPED ||
-                   child->signal->group_stop_count)
-                       __set_task_state(child, TASK_STOPPED);
-               else
-                       signal_wake_up(child, 1);
-       }
-       spin_unlock(&child->sighand->siglock);
-}
-
-/*
  * unptrace a task: move it back to its original parent and
  * remove it from the ptrace list.
  *
@@ -150,8 +145,6 @@ void __ptrace_unlink(struct task_struct 
        list_del_init(&child->ptrace_entry);
 
        arch_ptrace_untrace(child);
-       if (task_is_traced(child))
-               ptrace_untrace(child);
 }
 
 /*
@@ -590,7 +583,7 @@ static int ptrace_resume(struct task_str
        }
 
        child->exit_code = data;
-       wake_up_process(child);
+       ptrace_wake_up(child);
 
        return 0;
 }

Reply via email to