It seems there are some kernels around where the getpid system call has
been changed to return the ID of the thread group leader but which do not
have a gettid system call.

This breaks VG_(gettid) which assumes that the getpid system call will
give the thread ID if the gettid system call does not exist.

The (horrible) solution is to use readlink to see where /proc/self points
when the gettid system call fails.

BUG: 82114


git-svn-id: svn://svn.valgrind.org/valgrind/trunk@2771 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/coregrind/vg_mylibc.c b/coregrind/vg_mylibc.c
index 3929490..691804c 100644
--- a/coregrind/vg_mylibc.c
+++ b/coregrind/vg_mylibc.c
@@ -232,8 +232,27 @@
 
    ret = VG_(do_syscall)(__NR_gettid);
 
-   if (ret == -VKI_ENOSYS)
-      ret = VG_(do_syscall)(__NR_getpid);
+   if (ret == -VKI_ENOSYS) {
+      Char pid[16];
+      
+      /*
+       * The gettid system call does not exist. The obvious assumption
+       * to make at this point would be that we are running on an older
+       * system where the getpid system call actually returns the ID of
+       * the current thread.
+       *
+       * Unfortunately it seems that there are some systems with a kernel
+       * where getpid has been changed to return the ID of the thread group
+       * leader but where the gettid system call has not yet been added.
+       *
+       * So instead of calling getpid here we use readlink to see where
+       * the /proc/self link is pointing...
+       */
+      if ((ret = VG_(do_syscall)(__NR_readlink, "/proc/self", pid, sizeof(pid))) >= 0) {
+         pid[ret] = '\0';
+         ret = VG_(atoll)(pid);
+      }
+   }
 
    return ret;
 }