diff options
author | Jeff Dike <jdike@addtoit.com> | 2005-06-08 15:48:13 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-06-08 16:21:12 -0700 |
commit | 501cb02b431fb88c7f157c46c8b54de59d1dd463 (patch) | |
tree | e41592306301f7bbd727466ca1a4b4b0f93751cf /arch/um | |
parent | da00d9a5466558ccd9e7b7d04b13d7cb9160c876 (diff) | |
download | linux-stable-501cb02b431fb88c7f157c46c8b54de59d1dd463.tar.gz linux-stable-501cb02b431fb88c7f157c46c8b54de59d1dd463.tar.bz2 linux-stable-501cb02b431fb88c7f157c46c8b54de59d1dd463.zip |
[PATCH] uml: fix strace -f
It turns out that we need to check for pending signals when a newly forked
process is run for the first time. With strace -f, strace needs to know about
the forked process before it gets going. If it doesn't, then it ptraces some
bogus values into its registers, and the process segfaults. So, I added calls
to interrupt_end, which does that, plus checks for reschedules. There
shouldn't be any of those, but x86 does the same thing, so I'm copying that
behavior to be safe.
Signed-off-by: Jeff Dike <jdike@addtoit.com>
Cc: Paolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/um')
-rw-r--r-- | arch/um/kernel/skas/process_kern.c | 7 |
1 files changed, 6 insertions, 1 deletions
diff --git a/arch/um/kernel/skas/process_kern.c b/arch/um/kernel/skas/process_kern.c index ab5d3271da0b..fc71ef295782 100644 --- a/arch/um/kernel/skas/process_kern.c +++ b/arch/um/kernel/skas/process_kern.c @@ -68,8 +68,11 @@ void new_thread_handler(int sig) * 0 if it just exits */ n = run_kernel_thread(fn, arg, ¤t->thread.exec_buf); - if(n == 1) + if(n == 1){ + /* Handle any immediate reschedules or signals */ + interrupt_end(); userspace(¤t->thread.regs.regs); + } else do_exit(0); } @@ -96,6 +99,8 @@ void fork_handler(int sig) schedule_tail(current->thread.prev_sched); current->thread.prev_sched = NULL; + /* Handle any immediate reschedules or signals */ + interrupt_end(); userspace(¤t->thread.regs.regs); } |