On top of http://people.redhat.com/roland/utrace/2.6-current/utrace-ptrace.patch

We need a starting point: a patch which at least partly works. To discuss
the actual changes, to have the ability to test things, etc.

But, due to discussed task_ptrace() problems, the patch above can't work
in any way. So I just removed the old code for now.

With this patch the kernel boots, but ptrace is not useable: the kernel
crashes very quickly during 'make check' (ptrace-tests). It crashes on
"random" test, usually 3-5 is enough.

I spent some time trying to investigate, but then decided it doesn't make
sense _now_. I suspect, the partly-detach logic is the main offender. We
will see.

---

 include/linux/ptrace.h    |   41 -----------
 include/linux/tracehook.h |   40 -----------
 kernel/ptrace.c           |  163 ----------------------------------------------
 kernel/utrace.c           |   15 ----
 4 files changed, 2 insertions(+), 257 deletions(-)

--- PU/include/linux/ptrace.h~01_REMOVE_OLD_CODE        2009-08-11 
16:54:21.000000000 +0200
+++ PU/include/linux/ptrace.h   2009-08-13 15:19:18.000000000 +0200
@@ -120,7 +120,6 @@ static inline void ptrace_unlink(struct 
 int generic_ptrace_peekdata(struct task_struct *tsk, long addr, long data);
 int generic_ptrace_pokedata(struct task_struct *tsk, long addr, long data);
 
-#ifndef CONFIG_UTRACE_PTRACE
 /**
  * task_ptrace - return %PT_* flags that apply to a task
  * @task:      pointer to &task_struct in question
@@ -132,48 +131,8 @@ static inline int task_ptrace(struct tas
        return task->ptrace;
 }
 
-/**
- * ptrace_event - possibly stop for a ptrace event notification
- * @mask:      %PT_* bit to check in @current->ptrace
- * @event:     %PTRACE_EVENT_* value to report if @mask is set
- * @message:   value for %PTRACE_GETEVENTMSG to return
- *
- * This checks the @mask bit to see if ptrace wants stops for this event.
- * If so we stop, reporting @event and @message to the ptrace parent.
- *
- * Returns nonzero if we did a ptrace notification, zero if not.
- *
- * Called without locks.
- */
-static inline int ptrace_event(int mask, int event, unsigned long message)
-{
-       if (mask && likely(!(current->ptrace & mask)))
-               return 0;
-       current->ptrace_message = message;
-       ptrace_notify((event << 8) | SIGTRAP);
-       return 1;
-}
-
-static inline void ptrace_utrace_exit(struct task_struct *task)
-{
-}
-
-#else  /* CONFIG_UTRACE_PTRACE */
-
-static inline int task_ptrace(struct task_struct *task)
-{
-       return 0;
-}
-
-static inline int ptrace_event(int mask, int event, unsigned long message)
-{
-       return 0;
-}
-
 extern void ptrace_utrace_exit(struct task_struct *);
 
-#endif /* !CONFIG_UTRACE_PTRACE */
-
 /**
  * ptrace_init_task - initialize ptrace state for a new child
  * @child:             new child task
--- PU/include/linux/tracehook.h~01_REMOVE_OLD_CODE     2009-08-11 
16:54:21.000000000 +0200
+++ PU/include/linux/tracehook.h        2009-08-13 15:50:27.000000000 +0200
@@ -69,29 +69,6 @@ static inline int tracehook_expect_break
        return (task_ptrace(task) & PT_PTRACED) != 0;
 }
 
-/*
- * ptrace report for syscall entry and exit looks identical.
- */
-static inline void ptrace_report_syscall(struct pt_regs *regs)
-{
-       int ptrace = task_ptrace(current);
-
-       if (!(ptrace & PT_PTRACED))
-               return;
-
-       ptrace_notify(SIGTRAP | ((ptrace & PT_TRACESYSGOOD) ? 0x80 : 0));
-
-       /*
-        * this isn't the same as continuing with a signal, but it will do
-        * for normal use.  strace only continues with a signal if the
-        * stopping signal is not SIGTRAP.  -brl
-        */
-       if (current->exit_code) {
-               send_sig(current->exit_code, current, 1);
-               current->exit_code = 0;
-       }
-}
-
 /**
  * tracehook_report_syscall_entry - task is about to attempt a system call
  * @regs:              user register state of current task
@@ -117,7 +94,6 @@ static inline __must_check int tracehook
        if ((task_utrace_flags(current) & UTRACE_EVENT(SYSCALL_ENTRY)) &&
            utrace_report_syscall_entry(regs))
                return 1;
-       ptrace_report_syscall(regs);
        return 0;
 }
 
@@ -142,7 +118,6 @@ static inline void tracehook_report_sysc
 {
        if (task_utrace_flags(current) & UTRACE_EVENT(SYSCALL_EXIT))
                utrace_report_syscall_exit(regs);
-       ptrace_report_syscall(regs);
 }
 
 /**
@@ -156,7 +131,7 @@ static inline void tracehook_report_sysc
 static inline int tracehook_unsafe_exec(struct task_struct *task)
 {
        int unsafe = 0;
-       int ptrace = task->ptrace;
+       int ptrace = task_ptrace(task);
        if (ptrace & PT_PTRACED) {
                if (ptrace & PT_PTRACE_CAP)
                        unsafe |= LSM_UNSAFE_PTRACE_CAP;
@@ -179,7 +154,7 @@ static inline int tracehook_unsafe_exec(
  */
 static inline struct task_struct *tracehook_tracer_task(struct task_struct 
*tsk)
 {
-       if (tsk->ptrace & PT_PTRACED)
+       if (task_ptrace(tsk) & PT_PTRACED)
                return rcu_dereference(tsk->parent);
        return NULL;
 }
@@ -204,9 +179,6 @@ static inline void tracehook_report_exec
 {
        if (unlikely(task_utrace_flags(current) & UTRACE_EVENT(EXEC)))
                utrace_report_exec(fmt, bprm, regs);
-       if (!ptrace_event(PT_TRACE_EXEC, PTRACE_EVENT_EXEC, 0) &&
-           unlikely(task_ptrace(current) & PT_PTRACED))
-               send_sig(SIGTRAP, current, 0);
 }
 
 /**
@@ -223,7 +195,6 @@ static inline void tracehook_report_exit
 {
        if (unlikely(task_utrace_flags(current) & UTRACE_EVENT(EXIT)))
                utrace_report_exit(exit_code);
-       ptrace_event(PT_TRACE_EXIT, PTRACE_EVENT_EXIT, *exit_code);
        if (unlikely(!list_empty(&current->ptraced)))
                ptrace_utrace_exit(current);
 }
@@ -330,8 +301,6 @@ static inline void tracehook_report_clon
        if (unlikely(task_utrace_flags(current) & UTRACE_EVENT(CLONE)) &&
            (clone_flags & CLONE_VFORK))
                utrace_finish_vfork(current);
-       if (unlikely(trace))
-               ptrace_event(0, trace, pid);
 }
 
 /**
@@ -349,7 +318,6 @@ static inline void tracehook_report_clon
 static inline void tracehook_report_vfork_done(struct task_struct *child,
                                               pid_t pid)
 {
-       ptrace_event(PT_TRACE_VFORK_DONE, PTRACE_EVENT_VFORK_DONE, pid);
 }
 
 /**
@@ -403,10 +371,6 @@ static inline void tracehook_signal_hand
 {
        if (task_utrace_flags(current))
                utrace_signal_handler(current, stepping);
-#ifndef CONFIG_UTRACE_PTRACE
-       if (stepping)
-               ptrace_notify(SIGTRAP);
-#endif
 }
 
 /**
--- PU/kernel/ptrace.c~01_REMOVE_OLD_CODE       2009-08-11 16:54:21.000000000 
+0200
+++ PU/kernel/ptrace.c  2009-08-13 15:34:29.000000000 +0200
@@ -38,46 +38,6 @@ void __ptrace_link(struct task_struct *c
        child->parent = new_parent;
 }
 
-#ifndef CONFIG_UTRACE_PTRACE
-/*
- * 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);
-}
-
-static void ptrace_finish(struct task_struct *child)
-{
-       if (task_is_traced(child))
-               ptrace_untrace(child);
-}
-
-static void ptrace_detach_task(struct task_struct *child, int sig)
-{
-       /* Architecture-specific hardware disable .. */
-       ptrace_disable(child);
-       clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
-}
-
-#else  /* CONFIG_UTRACE_PTRACE */
-
 static const struct utrace_engine_ops ptrace_utrace_ops; /* forward decl */
 
 static void ptrace_detach_task(struct task_struct *child, int sig)
@@ -119,12 +79,6 @@ void ptrace_utrace_exit(struct task_stru
        read_unlock(&tasklist_lock);
 }
 
-static void ptrace_finish(struct task_struct *child)
-{
-}
-
-#endif /* !CONFIG_UTRACE_PTRACE */
-
 /*
  * unptrace a task: move it back to its original parent and
  * remove it from the ptrace list.
@@ -140,72 +94,11 @@ void __ptrace_unlink(struct task_struct 
        list_del_init(&child->ptrace_entry);
 
        arch_ptrace_untrace(child);
-       ptrace_finish(child);
-}
-
-#ifndef CONFIG_UTRACE_PTRACE
-
-/*
- * Check that we have indeed attached to the thing..
- */
-int ptrace_check_attach(struct task_struct *child, int kill)
-{
-       int ret = -ESRCH;
-
-       /*
-        * We take the read lock around doing both checks to close a
-        * possible race where someone else was tracing our child and
-        * detached between these two checks.  After this locked check,
-        * we are sure that this is our traced child and that can only
-        * be changed by us so it's not changing right after this.
-        */
-       read_lock(&tasklist_lock);
-       if ((child->ptrace & PT_PTRACED) && child->parent == current) {
-               ret = 0;
-               /*
-                * child->sighand can't be NULL, release_task()
-                * does ptrace_unlink() before __exit_signal().
-                */
-               spin_lock_irq(&child->sighand->siglock);
-               if (task_is_stopped(child))
-                       child->state = TASK_TRACED;
-               else if (!task_is_traced(child) && !kill)
-                       ret = -ESRCH;
-               spin_unlock_irq(&child->sighand->siglock);
-       }
-       read_unlock(&tasklist_lock);
-
-       if (!ret && !kill)
-               ret = wait_task_inactive(child, TASK_TRACED) ? 0 : -ESRCH;
-
-       /* All systems go.. */
-       return ret;
-}
-
-static struct utrace_engine *prepare_ptrace_attach(
-       struct task_struct *child, struct task_struct *parent)
-{
-       return NULL;
-}
-
-static int finish_ptrace_attach(struct task_struct *task,
-                                struct utrace_engine *engine,
-                                int retval)
-{
-       return retval;
 }
 
 static int ptrace_update_utrace(struct task_struct *task,
                                struct utrace_engine *engine)
 {
-       return 0;
-}
-
-#else  /* CONFIG_UTRACE_PTRACE */
-
-static int ptrace_update_utrace(struct task_struct *task,
-                               struct utrace_engine *engine)
-{
        unsigned long events;
 
        /*
@@ -702,8 +595,6 @@ int ptrace_check_attach(struct task_stru
        return ret;
 }
 
-#endif /* !CONFIG_UTRACE_PTRACE */
-
 int __ptrace_may_access(struct task_struct *task, unsigned int mode)
 {
        const struct cred *cred = current_cred(), *tcred;
@@ -751,21 +642,6 @@ bool ptrace_may_access(struct task_struc
        return !err;
 }
 
-#ifdef CONFIG_UTRACE_PTRACE
-static inline bool exclude_ptrace(struct task_struct *task)
-{
-       return false;
-}
-#else
-/*
- * For experimental use of utrace, exclude ptrace on the same task.
- */
-static inline bool exclude_ptrace(struct task_struct *task)
-{
-       return unlikely(!!task_utrace_flags(task));
-}
-#endif
-
 int ptrace_attach(struct task_struct *task)
 {
        int retval;
@@ -794,8 +670,6 @@ int ptrace_attach(struct task_struct *ta
 
        task_lock(task);
        retval = __ptrace_may_access(task, PTRACE_MODE_ATTACH);
-       if (!retval && exclude_ptrace(task))
-               retval = -EBUSY;
        task_unlock(task);
        if (retval)
                goto unlock_creds;
@@ -1087,42 +961,6 @@ static int ptrace_setsiginfo(struct task
 #define is_sysemu_singlestep(request)  0
 #endif
 
-#ifndef CONFIG_UTRACE_PTRACE
-static int ptrace_resume(struct task_struct *child, long request, long data)
-{
-       if (!valid_signal(data))
-               return -EIO;
-
-       if (request == PTRACE_SYSCALL)
-               set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
-       else
-               clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
-
-#ifdef TIF_SYSCALL_EMU
-       if (request == PTRACE_SYSEMU || request == PTRACE_SYSEMU_SINGLESTEP)
-               set_tsk_thread_flag(child, TIF_SYSCALL_EMU);
-       else
-               clear_tsk_thread_flag(child, TIF_SYSCALL_EMU);
-#endif
-
-       if (is_singleblock(request)) {
-               if (unlikely(!arch_has_block_step()))
-                       return -EIO;
-               user_enable_block_step(child);
-       } else if (is_singlestep(request) || is_sysemu_singlestep(request)) {
-               if (unlikely(!arch_has_single_step()))
-                       return -EIO;
-               user_enable_single_step(child);
-       } else {
-               user_disable_single_step(child);
-       }
-
-       child->exit_code = data;
-       wake_up_process(child);
-
-       return 0;
-}
-#else  /* CONFIG_UTRACE_PTRACE */
 static int ptrace_resume(struct task_struct *child, long request, long data)
 {
        struct utrace_engine *engine;
@@ -1285,7 +1123,6 @@ static int ptrace_resume(struct task_str
 
        return ret;
 }
-#endif /* !CONFIG_UTRACE_PTRACE */
 
 int ptrace_request(struct task_struct *child, long request,
                   long addr, long data)
--- PU/kernel/utrace.c~01_REMOVE_OLD_CODE       2009-08-11 16:54:21.000000000 
+0200
+++ PU/kernel/utrace.c  2009-08-13 15:10:55.000000000 +0200
@@ -107,21 +107,6 @@ static struct utrace_engine *matching_en
        return NULL;
 }
 
-#ifdef CONFIG_UTRACE_PTRACE
-static inline bool exclude_utrace(struct task_struct *task)
-{
-       return false;
-}
-#else
-/*
- * For experimental use, utrace attach is mutually exclusive with ptrace.
- */
-static inline bool exclude_utrace(struct task_struct *task)
-{
-       return unlikely(!!task->ptrace);
-}
-#endif
-
 /*
  * Called without locks, when we might be the first utrace engine to attach.
  * If this is a newborn thread and we are not the creator, we have to wait

Reply via email to