Commit 8b64cc97 authored by Paolo \'Blaisorblade\' Giarrusso's avatar Paolo \'Blaisorblade\' Giarrusso Committed by Linus Torvalds

[PATCH] uml: fix ptrace() hang on 2.6.9 host due to host changes

From: Gerd Knorr <kraxel@bytesex.org>,
      Paolo 'Blaisorblade' Giarrusso <blaisorblade_spam@yahoo.it>

Uml was using kill(pid, SIGKILL) instead of ptrace(PTRACE_KILL, pid), which
used to work, while being probably undocumented.  Due to the changes in
2.6.9 to the ptrace(2) semantics, with the introduction of TASK_TRACED by
Roland McGrath, this does not more work, so this patch should fix it.

With help of Gerd Knorr report and analysis, and its early fix of this
problem.  He fixed the problem by sending SIGCONT to the child processes
after SIGKILL.  Which IMHO should not be needed (I think this is a
regression, which he already reported).

I improved his one, by replacing the SIGCONT hack with using PTRACE_KILL
instead.
Signed-off-by: default avatarPaolo 'Blaisorblade' Giarrusso <blaisorblade_spam@yahoo.it>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent af5d5df2
...@@ -157,6 +157,7 @@ extern unsigned long os_process_pc(int pid); ...@@ -157,6 +157,7 @@ extern unsigned long os_process_pc(int pid);
extern int os_process_parent(int pid); extern int os_process_parent(int pid);
extern void os_stop_process(int pid); extern void os_stop_process(int pid);
extern void os_kill_process(int pid, int reap_child); 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 void os_usr1_process(int pid);
extern int os_getpid(void); extern int os_getpid(void);
......
...@@ -389,7 +389,7 @@ void switch_mm_skas(int mm_fd) ...@@ -389,7 +389,7 @@ void switch_mm_skas(int mm_fd)
void kill_off_processes_skas(void) void kill_off_processes_skas(void)
{ {
#warning need to loop over userspace_pids in kill_off_processes_skas #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) void init_registers(int pid)
......
...@@ -82,7 +82,7 @@ void *switch_to_tt(void *prev, void *next, void *last) ...@@ -82,7 +82,7 @@ void *switch_to_tt(void *prev, void *next, void *last)
prev_sched = current->thread.prev_sched; prev_sched = current->thread.prev_sched;
if((prev_sched->exit_state == EXIT_ZOMBIE) || if((prev_sched->exit_state == EXIT_ZOMBIE) ||
(prev_sched->exit_state == EXIT_DEAD)) (prev_sched->exit_state == EXIT_DEAD))
os_kill_process(prev_sched->thread.mode.tt.extern_pid, 1); os_kill_ptraced_process(prev_sched->thread.mode.tt.extern_pid, 1);
/* This works around a nasty race with 'jail'. If we are switching /* This works around a nasty race with 'jail'. If we are switching
* between two threads of a threaded app and the incoming process * between two threads of a threaded app and the incoming process
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include <errno.h> #include <errno.h>
#include <signal.h> #include <signal.h>
#include <linux/unistd.h> #include <linux/unistd.h>
#include <sys/ptrace.h>
#include <sys/mman.h> #include <sys/mman.h>
#include <sys/wait.h> #include <sys/wait.h>
#include "os.h" #include "os.h"
...@@ -94,6 +95,13 @@ void os_kill_process(int pid, int reap_child) ...@@ -94,6 +95,13 @@ void os_kill_process(int pid, int reap_child)
} }
void os_kill_ptraced_process(int pid, int reap_child)
{
ptrace(PTRACE_KILL, pid);
if(reap_child)
CATCH_EINTR(waitpid(pid, NULL, 0));
}
void os_usr1_process(int pid) void os_usr1_process(int pid)
{ {
kill(pid, SIGUSR1); kill(pid, SIGUSR1);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment