2004-11-10 19:08:58

by Blaisorblade

[permalink] [raw]
Subject: [patch 1/1] uml: use sys_getpid bypassing glibc (fixes UML on Gentoo)


From: Bodo Stroesser <[email protected]>, Paolo 'Blaisorblade' Giarrusso <[email protected]>
Cc: Ulrich Drepper <[email protected]>

Using NPTL, getpid() sometimes delivers the wrong pid, since it uses the one
buffered in TLS from previous calls. This buffered pid isn't discarded, when
a child is created by a clone().

So, as a workaround, UML should use a direct kernel call to bypass the lib.

Also, I (Paolo) went replacing all remaining calls of getpid() with
os_getpid(), to make sure they use the syscall and not the normal glibc
definition.

Signed-off-by: Bodo Stroesser <[email protected]>
Signed-off-by: Paolo 'Blaisorblade' Giarrusso <[email protected]>
---

linux-2.6.10-rc-paolo/arch/um/kernel/frame.c | 8 ++++----
linux-2.6.10-rc-paolo/arch/um/kernel/main.c | 3 ++-
linux-2.6.10-rc-paolo/arch/um/kernel/skas/process.c | 2 +-
linux-2.6.10-rc-paolo/arch/um/os-Linux/process.c | 4 ++++
4 files changed, 11 insertions(+), 6 deletions(-)

diff -puN arch/um/os-Linux/process.c~uml-use-sys-getpid-bypassing-glibc arch/um/os-Linux/process.c
--- linux-2.6.10-rc/arch/um/os-Linux/process.c~uml-use-sys-getpid-bypassing-glibc 2004-11-10 18:24:10.000000000 +0100
+++ linux-2.6.10-rc-paolo/arch/um/os-Linux/process.c 2004-11-10 18:24:10.000000000 +0100
@@ -107,6 +107,10 @@ void os_usr1_process(int pid)
kill(pid, SIGUSR1);
}

+/*Don't use the glibc version, which caches the result in TLS. It misses some
+ * syscalls, and also breaks with clone(), which does not unshare the TLS.*/
+inline _syscall0(pid_t, getpid)
+
int os_getpid(void)
{
return(getpid());
diff -puN arch/um/kernel/skas/process.c~uml-use-sys-getpid-bypassing-glibc arch/um/kernel/skas/process.c
--- linux-2.6.10-rc/arch/um/kernel/skas/process.c~uml-use-sys-getpid-bypassing-glibc 2004-11-10 18:45:59.529650720 +0100
+++ linux-2.6.10-rc-paolo/arch/um/kernel/skas/process.c 2004-11-10 18:46:52.166648680 +0100
@@ -30,7 +30,7 @@

int is_skas_winch(int pid, int fd, void *data)
{
- if(pid != getpid())
+ if(pid != os_getpid())
return(0);

register_winch_irq(-1, fd, -1, data);
diff -puN arch/um/kernel/frame.c~uml-use-sys-getpid-bypassing-glibc arch/um/kernel/frame.c
--- linux-2.6.10-rc/arch/um/kernel/frame.c~uml-use-sys-getpid-bypassing-glibc 2004-11-10 18:45:59.564645400 +0100
+++ linux-2.6.10-rc-paolo/arch/um/kernel/frame.c 2004-11-10 18:46:52.168648376 +0100
@@ -140,7 +140,7 @@ static void child_common(struct common_r
}
if(sigaltstack(&ss, NULL) < 0){
printf("sigaltstack failed - errno = %d\n", errno);
- kill(getpid(), SIGKILL);
+ kill(os_getpid(), SIGKILL);
}

if(restorer){
@@ -162,7 +162,7 @@ static void child_common(struct common_r

if(err < 0){
printf("sigaction failed - errno = %d\n", errno);
- kill(getpid(), SIGKILL);
+ kill(os_getpid(), SIGKILL);
}

os_stop_process(os_getpid());
@@ -191,7 +191,7 @@ static void sc_handler(int sig, struct s
setup_arch_frame_raw(&raw_sc->common.arch, &sc + 1, raw_sc->common.sr);

os_stop_process(os_getpid());
- kill(getpid(), SIGKILL);
+ kill(os_getpid(), SIGKILL);
}

static int sc_child(void *arg)
@@ -229,7 +229,7 @@ static void si_handler(int sig, siginfo_
ucontext->uc_mcontext.fpregs, raw_si->common.sr);

os_stop_process(os_getpid());
- kill(getpid(), SIGKILL);
+ kill(os_getpid(), SIGKILL);
}

static int si_child(void *arg)
diff -puN arch/um/kernel/main.c~uml-use-sys-getpid-bypassing-glibc arch/um/kernel/main.c
--- linux-2.6.10-rc/arch/um/kernel/main.c~uml-use-sys-getpid-bypassing-glibc 2004-11-10 18:45:59.575643728 +0100
+++ linux-2.6.10-rc-paolo/arch/um/kernel/main.c 2004-11-10 18:49:05.002454568 +0100
@@ -26,6 +26,7 @@
#include "uml-config.h"
#include "irq_user.h"
#include "time_user.h"
+#include "os.h"

/* Set in set_stklim, which is called from main and __wrap_malloc.
* __wrap_malloc only calls it if main hasn't started.
@@ -175,7 +176,7 @@ int main(int argc, char **argv, char **e
}

#define CAN_KMALLOC() \
- (kmalloc_ok && CHOOSE_MODE((getpid() != tracing_pid), 1))
+ (kmalloc_ok && CHOOSE_MODE((os_getpid() != tracing_pid), 1))

extern void *__real_malloc(int);

_