Introduce ptrace_notify_stop(). It is used by utrace_stop() which currently
plays with ptrace internals.

Yes, this kludge is not perfect too. Until we add something more generic
to utrace.

---

 include/linux/ptrace.h |    2 +-
 kernel/utrace.c        |    8 ++------
 kernel/ptrace.c        |    9 +++++++++
 3 files changed, 12 insertions(+), 7 deletions(-)

--- PU/include/linux/ptrace.h~24_PTRACE_NOTIFY_STOP     2009-09-07 
19:32:21.000000000 +0200
+++ PU/include/linux/ptrace.h   2009-09-07 19:37:47.000000000 +0200
@@ -82,7 +82,7 @@
 #include <linux/compiler.h>            /* For unlikely.  */
 #include <linux/sched.h>               /* For struct task_struct.  */
 
-
+extern void ptrace_notify_stop(struct task_struct *tracee);
 extern long arch_ptrace(struct task_struct *child, long request, long addr, 
long data);
 extern int ptrace_traceme(void);
 extern int ptrace_readdata(struct task_struct *tsk, unsigned long src, char 
__user *dst, int len);
--- PU/kernel/utrace.c~24_PTRACE_NOTIFY_STOP    2009-09-07 17:34:23.000000000 
+0200
+++ PU/kernel/utrace.c  2009-09-07 19:50:14.000000000 +0200
@@ -409,12 +409,8 @@ static void utrace_stop(struct task_stru
         * be done after we are in TASK_TRACED.  This makes the
         * synchronization with ptrace_do_wait() work right.
         */
-       if (((task->ptrace >> 16) & UTRACE_RESUME_MASK) ==
-           UTRACE_RESUME - UTRACE_STOP) {
-               read_lock(&tasklist_lock);
-               do_notify_parent_cldstop(task, CLD_TRAPPED);
-               read_unlock(&tasklist_lock);
-       }
+       if (task_ptrace(task))
+               ptrace_notify_stop(task);
 #endif
 
        schedule();
--- PU/kernel/ptrace.c~24_PTRACE_NOTIFY_STOP    2009-09-07 17:33:08.000000000 
+0200
+++ PU/kernel/ptrace.c  2009-09-07 19:48:41.000000000 +0200
@@ -898,6 +898,15 @@ static int ptrace_setsiginfo(struct task
 #define is_sysemu_singlestep(request)  0
 #endif
 
+void ptrace_notify_stop(struct task_struct *tracee)
+{
+       if (ptrace_resume_action(tracee) == UTRACE_STOP) {
+               read_lock(&tasklist_lock);
+               do_notify_parent_cldstop(tracee, CLD_TRAPPED);
+               read_unlock(&tasklist_lock);
+       }
+}
+
 static int ptrace_resume(struct task_struct *child, long request, long data)
 {
        struct utrace_engine *engine;

Reply via email to