On 09/21, Oleg Nesterov wrote: > > Looks like, ptrace can't rely on user_enable_single_step(), unless the syscall > was entered with _TIF_SYSCALL_TRACE/_TIF_SINGLESTEP or we are going to return > with signal.
And there is another issue: finish_resume_report(UTRACE_RESUME) does user_disable_single_step(). Now I _hope_ I fully understand why my initial patch to handle PTRACE_SINGLESTEP didn't work. report_signal/quiesce should re-assert SINGLESTEP, it should be recorded in ptrace_context. With the test patch below on top of "[PATCH 50] ptrace_request: use ptrace_lookup_engine()" the kernel passes these tests step-jump-cont step-to-breakpoint step-simple These step-into-handler step-through-sigret fail, but I think this is understandable: ptrace_report_signal() doen't process UTRACE_SIGNAL_HANDLER yet. Now I need to think a bit more before I send the PTRACE_SINGLESTEP changes. And perhaps you can shed more light on enable_disable_single_step() magic... Oleg. --- PU/kernel/utrace.c~TF_FBG 2009-09-15 10:34:59.000000000 +0200 +++ PU/kernel/utrace.c 2009-09-21 22:42:15.000000000 +0200 @@ -1765,7 +1765,7 @@ static void finish_resume_report(struct case UTRACE_REPORT: case UTRACE_RESUME: default: - user_disable_single_step(task); + //user_disable_single_step(task); break; } } --- PU/kernel/ptrace.c~51_STEP_SIMPLE 2009-09-17 21:03:11.000000000 +0200 +++ PU/kernel/ptrace.c 2009-09-21 19:52:55.000000000 +0200 @@ -924,6 +924,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 +951,7 @@ static void do_ptrace_resume(struct utra } } - ptrace_wake_up(engine, tracee, UTRACE_RESUME); + ptrace_wake_up(engine, tracee, action); } static int ptrace_resume(struct utrace_engine *engine, @@ -992,7 +993,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; }