finish_report: if (will_not_stop && resume == UTRACE_STOP) resume = UTRACE_REPORT;
OK, this is to avoid the subsequent utrace_resume() report when we are going to stop. But the logic is wrong, ->resume must never be UTRACE_STOP. Once we set ->resume = UTRACE_STOP, we break every code which tries to update ->resume doing if (action < utrace->resume) utrace->resume = action; With this patch the kernel passes all tests except single-step ones, as expected. Signed-off-by: Oleg Nesterov <o...@redhat.com> --- kernel/utrace.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) --- UTRACE-PTRACE/kernel/utrace.c~UTRACE_RESUME_MUST_NOT_BE_STOP 2009-11-15 22:39:33.000000000 +0100 +++ UTRACE-PTRACE/kernel/utrace.c 2009-11-15 22:41:57.000000000 +0100 @@ -1357,8 +1357,10 @@ static void finish_report(struct task_st struct utrace_report *report, bool will_not_stop) { enum utrace_resume_action resume = report->action; - if (will_not_stop && resume == UTRACE_STOP) - resume = UTRACE_REPORT; + + if (resume == UTRACE_STOP) { + resume = will_not_stop ? UTRACE_REPORT : UTRACE_RESUME; + } if (resume < utrace->resume) { spin_lock(&utrace->lock);