Remove the current PTRACE_EVENT_VFORK_DONE logic, it doesn't really work anyway.
I failed to finish the re-implementation today, hopefully will complete on weekend. But I have 2 questions: 1. I assume that, on every arch, we alway check TIF_NOTIFY_RESUME and TIF_SIGPENDING before TIF_SYSCALL_TRACE, right? IOW, can I assume that syscall_trace_leave() should not be called before utrace_resume() or utrace_get_signal() ? This is true (afacs) for x86, but I am not sure about other arches. 2. We have to play tricks because there is no reporting loop tracehook_report_vfork_done(). Why? I agree, UTRACE_EVENT(VFROKDONE) is meaningless because we are going to return from syscall soon and the tracer can see this event "for free". But perhaps there is another reason I missed? And, otoh, why do we have PT_TRACE_VFORK_DONE ? If it is in fact useful, then perhaps UTRACE_EVENT(VFROKDONE) is useful too? Just curious, and confused a bit. --- kernel/ptrace.c | 55 +------------------------------------------------------ 1 file changed, 1 insertion(+), 54 deletions(-) --- PU/kernel/ptrace.c~30_KILL_VFORKDONE_LOGIC 2009-09-12 00:59:10.000000000 +0200 +++ PU/kernel/ptrace.c 2009-09-12 01:04:59.000000000 +0200 @@ -230,22 +230,6 @@ static u32 ptrace_report_clone(enum utra struct ptrace_context *context = ptrace_context(engine); int event; - if ((clone_flags & CLONE_VFORK) && - (context->options & PTRACE_O_TRACEVFORKDONE)) { - /* - * Stash the child PID for a PTRACE_EVENT_VFORK_DONE report, - * even if we don't report this clone event itself. Mark - * that we vfork'd even if we don't actually stop here, so - * that we'll know to do the vfork-done report. (This - * matters when is PTRACE_O_TRACEVFORKDONE set but - * PTRACE_O_TRACEVFORK is not set.) - */ - int rc = utrace_control(parent, engine, UTRACE_REPORT); - WARN_ON(rc); - parent->ptrace_message = child->pid; - ptrace_set_stop_event(parent, PTRACE_EVENT_VFORK); - } - if (clone_flags & CLONE_UNTRACED) return UTRACE_RESUME; @@ -298,24 +282,6 @@ static u32 ptrace_report_syscall_entry(u return ptrace_report_syscall(UTRACE_SYSCALL_RUN, engine, task); } -/* - * Report a vfork-done event to precede another event report. - * There is no utrace callback associated directly with vfork-done. - * Instead, after seeing CLONE_VFORK in report_clone() we notice - * the following syscall-exit, signal, or quiesce callback and - * inject the PTRACE_EVENT_VFORK_DONE stop there. - */ -static u32 ptrace_report_vfork_done(struct task_struct *task) -{ - /* - * We got here after a vfork, when vfork-done tracing - * was enabled. - */ - ptrace_set_stop_event(task, 0); - return utrace_ptrace_event(task, PTRACE_EVENT_VFORK_DONE, - task->ptrace_message); -} - static void ptrace_wake_up(struct utrace_engine *engine, struct task_struct *tracee, enum utrace_resume_action action) @@ -370,9 +336,6 @@ static u32 ptrace_resumed(struct task_st { enum utrace_resume_action resume = ptrace_resume_action(task); - if (unlikely(ptrace_stop_event(task) == PTRACE_EVENT_VFORK)) - return UTRACE_SIGNAL_REPORT | ptrace_report_vfork_done(task); - /* * If we're stopping, or we haven't reported any signal, * then we're all done for now. @@ -480,9 +443,6 @@ static u32 ptrace_report_quiesce(u32 act if (event == 0) { task->last_siginfo = NULL; - - if (unlikely(ptrace_stop_event(task) == PTRACE_EVENT_VFORK)) - return ptrace_report_vfork_done(task); } return ptrace_resume_action(task); @@ -1090,20 +1050,7 @@ static int ptrace_resume(struct task_str break; case PTRACE_EVENT_VFORK: - /* - * For this event, @data is ignored. We did have a - * utrace stop right after, so on resuming there - * can be a normal syscall-exit stop next if needed. - * But we may need to simulate a vfork-done stop, - * so we leave the marker in place. - */ - data = 0; - event = 0; - if (context->options & PTRACE_O_TRACEVFORKDONE) { - ptrace_set_stop_event(child, - PTRACE_EVENT_VFORK); - action = UTRACE_REPORT; - } + WARN_ON(1); break; }