This is the temporary fix for the new step-from-clone.c test-case.
Actually kludge, not the fix. But I don't understand the rationale
behind the current behaviour yet.

So, this test does:

        ptrace(PTRACE_SETOPTIONS, PTRACE_O_TRACESYSGOOD);

        ptrace(PTRACE_CONT);

        // tracee reports PTRACE_EVENT_FORK

        ptrace(PTRACE_SINGLESTEP)

Now the tracer expects to get the notification from syscall-exit stop
for "fork ()", but at the same time it expects

        assert ((status >> 8) == SIGTRAP);

This looks a bit strange to me, usually PTRACE_O_TRACESYSGOOD adds 0x80.
Yes, I understand why this happens with the vanilla kernel, without
PTRACE_SYSCALL TIF_SYSCALL_FTRACE is not set when syscall_trace_leave()
is called, we got this report due to send_sigtrap().

And send_sigtrap() means we really report the signal, I mean utrace-ptrace
should do send_sigtrap() too, not just report SIGTRAP. We need the valid
context->siginfo which indicates the tracer can change/clear ->si_signo
on resume. And of course, we can't rely on syscall_trace_leave() in this
case, we stop before return to the user-mode after syscall_trace_leave()
was already called.

Oh. I'll fix this later.

---

 kernel/ptrace.c |    8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

--- PU/kernel/ptrace.c~55_STEP_IGNORES_TRACESYSGOOD     2009-09-23 
21:52:46.000000000 +0200
+++ PU/kernel/ptrace.c  2009-09-23 22:26:59.000000000 +0200
@@ -267,8 +267,9 @@ static void push_syscall_event(struct pt
 
        ev->ev_options = PTRACE_O_TRACE_SYSCALL;
        ev->ev_resume = ptrace_resume_syscall;
-       ev->ev_code = (context->options & PTRACE_O_TRACESYSGOOD) ?
-                       (SIGTRAP | 0x80) : SIGTRAP;
+       ev->ev_code =   (context->options & PTRACE_O_TRACESYSGOOD) &&
+                       (context->resume == UTRACE_RESUME) ?
+                               (SIGTRAP | 0x80) : SIGTRAP;
 }
 
 static u32 ptrace_report_syscall_entry(u32 action,
@@ -952,6 +953,8 @@ static void do_ptrace_resume(struct utra
        else
                context->options &= ~PTRACE_O_TRACE_SYSCALL;
 
+       context->resume = action;
+
        if (!ev_empty(context)) {
                struct ptrace_event *ev = ev_pop(context);
 
@@ -969,7 +972,6 @@ static void do_ptrace_resume(struct utra
                }
        }
 
-       context->resume = action;
        ptrace_wake_up(engine, tracee, action);
 }
 

Reply via email to