On 10/29, Oleg Nesterov wrote: > > On 10/27, Roland McGrath wrote: > > > > > + case PTRACE_KILL: > > > + ret = 0; > > > + if (!child->exit_state) /* already dead */ > > > + ret = ptrace_resume(child, engine, request, SIGKILL); > > > + break; > > > > This could be inside ptrace_resume too. > > Yes, and we don't even need to check exit_state.
Damn, this PTRACE_KILL is so weird. If we move this "case:" into ptrace_resume() path, then we have to make sure we do not return -ESRCH if request == SIGKILL (or we can ignore this incompatibility?) Apart from that, what it should actually do? If the tracee was STOPPED/TRACED, then it is equivalent to PTRACE_CONT,SIGKILL. Otherwise it has no effect except it can race with exit() and spoil ->exit_code, and wake_up_process() is not good if course. (I am talking about upstream). Perhaps it is better to leave this strange and special case in ptrace_request() like this patch does? Otherwise, we can change ptrace_resume() to never return the error if, say, utrace_set_events() fails, but while this is correct it looks a bit ugly. Please tell me what do you think, then I'll do other changes you suggested. --- kernel/ptrace.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) --- PU/kernel/ptrace.c~122_PTRACE_KILL 2009-10-26 03:18:12.000000000 +0100 +++ PU/kernel/ptrace.c 2009-10-30 04:00:15.000000000 +0100 @@ -1000,9 +1000,10 @@ int ptrace_request(struct task_struct *c break; case PTRACE_KILL: + /* Ugly historical behaviour. */ + if (task_is_traced(child)) + ptrace_resume(child, engine, PTRACE_CONT, SIGKILL); ret = 0; - if (!child->exit_state) /* already dead */ - ret = ptrace_resume(child, engine, request, SIGKILL); break; default: