In short, it is just wrong to call finish_resume_report() in utrace_resume() without reporting loop, because utrace never clears TIF_NOTIFY_RESUME. It is very possible we enter utrace_resume() with utrace->resume == UTRACE_RESUME, in this case finish_resume_report() does user_disable_single_step(). And if TIF_SINGLESTEP was previously set by utrace_get_signal() which noticed ->resume < UTRACE_RESUME we lost: engine can't re-assert the stepping.
IOW. Just one example. The tracee reports the signal and sleeps in utrace_get_signal()->finish_resume_report(). Suppose that the tracee has TIF_NOTIFY_RESUME bit set. A lot of reasons why this can happen. The tracer wakes up the tracee via utrace_control(UTRACE_SINGLESTEP). The tracee resumes, calls utrace_get_signal_again(), notices utrace->resume < UTRACE_RESUME, resets utrace->resume, and does finish_resume_report()->enable_step() correctly. But, since TIF_NOTIFY_RESUME is set, the tracee will call utrace_resume() before return to user-mode, and the next finish_resume_report() from utrace_resume() clears TIF_SINGLESTEP. Of course, this is just the temporary hack, to do the testing right now. I still do not understand the new code in details, need to read it carefully but didn't have the time yet :/ --- kernel/utrace.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) --- UTRACE-PTRACE/kernel/utrace.c~UTRACE_HACK_RESUME 2009-11-16 17:02:11.000000000 +0100 +++ UTRACE-PTRACE/kernel/utrace.c 2009-11-16 17:28:10.000000000 +0100 @@ -1871,7 +1871,7 @@ void utrace_resume(struct task_struct *t */ report.action = start_report(utrace); - if (report.action == UTRACE_REPORT && + if (1 && //report.action == UTRACE_REPORT && likely(task->utrace_flags & UTRACE_EVENT(QUIESCE))) { /* * Do a simple reporting pass, with no specific