diff -aur -X diff-exclude 2.4.27-1um-orig/arch/um/include/os.h 2.4.27-1um-zombiefix/arch/um/include/os.h --- 2.4.27-1um-orig/arch/um/include/os.h 2004-11-27 06:45:42.410794178 -0500 +++ 2.4.27-1um-zombiefix/arch/um/include/os.h 2004-11-27 07:13:25.295431403 -0500 @@ -190,6 +190,7 @@ extern int os_process_parent(int pid); extern void os_stop_process(int pid); extern void os_kill_process(int pid, int reap_child); +extern void os_kill_ptraced_process(int pid, int reap_child); extern void os_usr1_process(int pid); extern int os_getpid(void); diff -aur -X diff-exclude 2.4.27-1um-orig/arch/um/kernel/skas/process.c 2.4.27-1um-zombiefix/arch/um/kernel/skas/process.c --- 2.4.27-1um-orig/arch/um/kernel/skas/process.c 2004-11-27 06:45:42.439787354 -0500 +++ 2.4.27-1um-zombiefix/arch/um/kernel/skas/process.c 2004-11-27 07:07:51.091085284 -0500 @@ -362,7 +362,7 @@ void kill_off_processes_skas(void) { #warning need to loop over userspace_pids in kill_off_processes_skas - os_kill_process(userspace_pid[0], 1); + os_kill_ptraced_process(userspace_pid[0], 1); } void init_registers(int pid) diff -aur -X diff-exclude 2.4.27-1um-orig/arch/um/kernel/tt/exec_user.c 2.4.27-1um-zombiefix/arch/um/kernel/tt/exec_user.c --- 2.4.27-1um-orig/arch/um/kernel/tt/exec_user.c 2004-11-27 06:45:42.448785237 -0500 +++ 2.4.27-1um-zombiefix/arch/um/kernel/tt/exec_user.c 2004-11-27 07:06:18.340913634 -0500 @@ -35,7 +35,7 @@ tracer_panic("do_exec failed to get registers - errno = %d", errno); - kill(old_pid, SIGKILL); + os_kill_ptraced_process(old_pid, 0); if(ptrace_setregs(new_pid, regs) < 0) tracer_panic("do_exec failed to start new proc - errno = %d", diff -aur -X diff-exclude 2.4.27-1um-orig/arch/um/kernel/tt/tracer.c 2.4.27-1um-zombiefix/arch/um/kernel/tt/tracer.c --- 2.4.27-1um-orig/arch/um/kernel/tt/tracer.c 2004-11-27 06:45:42.458782883 -0500 +++ 2.4.27-1um-zombiefix/arch/um/kernel/tt/tracer.c 2004-11-27 07:06:10.502758310 -0500 @@ -313,7 +313,13 @@ case OP_HALT: unmap_physmem(); kmalloc_ok = 0; - ptrace(PTRACE_KILL, pid, 0, 0); + os_kill_ptraced_process(pid, 0); + /* Now let's reap remaining zombies */ + errno = 0; + do { + waitpid(-1, &status, + WUNTRACED); + } while (errno != ECHILD); return(op == OP_REBOOT); case OP_NONE: printf("Detaching pid %d\n", pid); diff -aur -X diff-exclude 2.4.27-1um-orig/arch/um/os-Linux/process.c 2.4.27-1um-zombiefix/arch/um/os-Linux/process.c --- 2.4.27-1um-orig/arch/um/os-Linux/process.c 2004-11-27 06:45:42.470780060 -0500 +++ 2.4.27-1um-zombiefix/arch/um/os-Linux/process.c 2004-11-27 07:34:23.439282608 -0500 @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include "os.h" @@ -85,12 +86,26 @@ kill(pid, SIGSTOP); } + void os_kill_process(int pid, int reap_child) { + kill(pid, SIGKILL); + if(reap_child) + CATCH_EINTR(waitpid(pid, NULL, 0)); +} + +/* Kill off a ptraced child by all means available. kill it normally first, + * then PTRACE_KILL it, then PTRACE_CONT it in case it's in a run state from + * which it can't exit directly. + */ + +void os_kill_ptraced_process(int pid, int reap_child) +{ kill(pid, SIGKILL); + ptrace(PTRACE_KILL, pid); + ptrace(PTRACE_CONT, pid); if(reap_child) CATCH_EINTR(waitpid(pid, NULL, 0)); - } void os_usr1_process(int pid)