Message ID | 20140509222324.795042C3A01@topped-with-meat.com |
---|---|
State | New |
Headers | show |
On Fri, May 09, 2014 at 03:23:24PM -0700, Roland McGrath wrote: > In looking at consolidating the NPTL vs not versions of vfork, I came > across the single, bizarre difference between the libpthread and libc > versions of vfork. This is implemented by a few lines of assembly for each > machine, and nowhere is there a comment that explains the rationale. > > The code in question is fiddling with the pid field of 'struct pthread'. I think there are several open race-condition bugs that amount to the pid caching glibc does being invalid in certain corner cases. Would you review them as part of looking at this issue? Rich
> I think there are several open race-condition bugs that amount to the > pid caching glibc does being invalid in certain corner cases. Would > you review them as part of looking at this issue? I'm only talking about what I'm talking about, which does not include any known bugs. If you know of any bugs, then file bugzilla reports for them and elaborate on the precise details. Thanks, Roland
On Tue, May 13, 2014 at 10:39:14AM -0700, Roland McGrath wrote: > > I think there are several open race-condition bugs that amount to the > > pid caching glibc does being invalid in certain corner cases. Would > > you review them as part of looking at this issue? > > I'm only talking about what I'm talking about, which does not include any > known bugs. If you know of any bugs, then file bugzilla reports for them > and elaborate on the precise details. There are at least a couple with open bug reports that seem to be related to this issue: 12889 and 15368. Rich
--- a/nptl/sysdeps/unix/sysv/linux/getpid.c +++ b/nptl/sysdeps/unix/sysv/linux/getpid.c @@ -21,42 +21,17 @@ #include <sysdep.h> -#ifndef NOT_IN_libc -static inline __attribute__((always_inline)) pid_t really_getpid (pid_t oldval); - -static inline __attribute__((always_inline)) pid_t -really_getpid (pid_t oldval) -{ - if (__glibc_likely (oldval == 0)) - { - pid_t selftid = THREAD_GETMEM (THREAD_SELF, tid); - if (__glibc_likely (selftid != 0)) - return selftid; - } - - INTERNAL_SYSCALL_DECL (err); - pid_t result = INTERNAL_SYSCALL (getpid, err, 0); - - /* We do not set the PID field in the TID here since we might be - called from a signal handler while the thread executes fork. */ - if (oldval == 0) - THREAD_SETMEM (THREAD_SELF, tid, result); - return result; -} -#endif - pid_t __getpid (void) { -#ifdef NOT_IN_libc - INTERNAL_SYSCALL_DECL (err); - pid_t result = INTERNAL_SYSCALL (getpid, err, 0); -#else +#ifndef NOT_IN_libc pid_t result = THREAD_GETMEM (THREAD_SELF, pid); - if (__glibc_unlikely (result <= 0)) - result = really_getpid (result); + if (__glibc_likely (result > 0)) + return result; #endif - return result; + + INTERNAL_SYSCALL_DECL (err); + return INTERNAL_SYSCALL (getpid, err, 0); } libc_hidden_def (__getpid)