[PATCH 5] utrace-ptrace-mini: make wakeups utrace-friendly

Oleg Nesterov oleg at redhat.com
Tue Aug 25 16:52:52 UTC 2009


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;
 }




More information about the utrace-devel mailing list