Change ptrace_resume() path to pass the correct "action" argument
to utrace_control(), the current code always uses UTRACE_RESUME
while PTRACE_SINGLEXXX needs UTRACE_XXXSTEP.

Introduce ptrace_context->resume to remember this action, we have
to re-assert it from report_quiesce/report_signal callbacks.

The next patch changes ptrace_report_signal(UTRACE_SIGNAL_HANDLER).

---

 kernel/ptrace.c |   25 ++++++++++++++++---------
 1 file changed, 16 insertions(+), 9 deletions(-)

--- PU/kernel/ptrace.c~51_STEP_SIMPLE   2009-09-17 21:03:11.000000000 +0200
+++ PU/kernel/ptrace.c  2009-09-23 00:50:28.000000000 +0200
@@ -25,7 +25,7 @@
 #include <linux/uaccess.h>
 
 typedef void (*resume_func_t)(struct utrace_engine *,
-                                       struct task_struct*, long);
+                               struct task_struct*, long);
 
 struct ptrace_event {
        int             ev_code;
@@ -42,6 +42,8 @@ struct ptrace_context {
 
        struct ptrace_event ev_array[2];
        unsigned int ev_first, ev_last;
+
+       enum utrace_resume_action resume;
 };
 
 static inline bool ev_empty(struct ptrace_context *context)
@@ -348,6 +350,7 @@ static u32 ptrace_report_signal(u32 acti
                                struct k_sigaction *return_ka)
 {
        struct ptrace_context *context = ptrace_context(engine);
+       enum utrace_resume_action resume = context->resume;
        struct ptrace_event *ev;
 
        if (!ev_empty(context)) {
@@ -362,27 +365,27 @@ static u32 ptrace_report_signal(u32 acti
                WARN_ON(1);
        case UTRACE_SIGNAL_REPORT:
                if (!context->siginfo)
-                       return UTRACE_RESUME | UTRACE_SIGNAL_IGN;
+                       return resume | UTRACE_SIGNAL_IGN;
 
                if (WARN_ON(context->siginfo != info))
-                       return UTRACE_RESUME | UTRACE_SIGNAL_IGN;
+                       return resume | UTRACE_SIGNAL_IGN;
                context->siginfo = NULL;
 
                if (!info->si_signo) // debugger cancelled sig
-                       return UTRACE_RESUME | UTRACE_SIGNAL_IGN;
+                       return resume | UTRACE_SIGNAL_IGN;
                /*
                 * If the (new) signal is now blocked, requeue it.
                 */
                if (sigismember(&task->blocked, info->si_signo)) {
                        send_sig_info(info->si_signo, info, task);
-                       return UTRACE_RESUME | UTRACE_SIGNAL_IGN;
+                       return resume | UTRACE_SIGNAL_IGN;
                }
 
                spin_lock_irq(&task->sighand->siglock);
                *return_ka = task->sighand->action[info->si_signo - 1];
                spin_unlock_irq(&task->sighand->siglock);
 
-               return UTRACE_RESUME | UTRACE_SIGNAL_DELIVER;
+               return resume | UTRACE_SIGNAL_DELIVER;
 
        default:
                WARN_ON(context->siginfo);
@@ -411,7 +414,7 @@ static u32 ptrace_report_quiesce(u32 act
                return UTRACE_STOP;
        }
 
-       return UTRACE_RESUME;
+       return event ? UTRACE_RESUME : context->resume;
 }
 
 static void ptrace_release(void *data)
@@ -463,6 +466,8 @@ static int ptrace_attach_task(struct tas
        if (unlikely(!context))
                return -ENOMEM;
 
+       context->resume = UTRACE_RESUME;
+
        engine = utrace_attach_task(tracee, UTRACE_ATTACH_CREATE |
                                                UTRACE_ATTACH_EXCLUSIVE |
                                                UTRACE_ATTACH_MATCH_OPS,
@@ -924,6 +929,7 @@ static void ptrace_wake_up(struct utrace
 
 static void do_ptrace_resume(struct utrace_engine *engine,
                                struct task_struct *tracee,
+                               enum utrace_resume_action action,
                                long request, long data)
 {
        struct ptrace_context *context = ptrace_context(engine);
@@ -950,7 +956,8 @@ static void do_ptrace_resume(struct utra
                }
        }
 
-       ptrace_wake_up(engine, tracee, UTRACE_RESUME);
+       context->resume = action;
+       ptrace_wake_up(engine, tracee, action);
 }
 
 static int ptrace_resume(struct utrace_engine *engine,
@@ -992,7 +999,7 @@ static int ptrace_resume(struct utrace_e
        }
 
        if (!ret)
-               do_ptrace_resume(engine, child, request, data);
+               do_ptrace_resume(engine, child, action, request, data);
 
        return ret;
 }

Reply via email to