[PATCH] fix test for vfork function
dalias at aerifal.cx
Fri Apr 27 05:07:42 UTC 2012
On Fri, Apr 27, 2012 at 12:58:33AM -0400, Mike Frysinger wrote:
> On Thursday 26 April 2012 23:08:36 Rich Felker wrote:
> > On Thu, Apr 26, 2012 at 10:50:57PM -0400, Mike Frysinger wrote:
> > > > This patch adds a test for __UCLIBC_VFORK_USES_CLONE__ feature
> > > > definition which an architecture may define if vfork is implemented
> > > > using clone.
> > >
> > > err, if your kernel arch doesn't have vfork, why is it defining
> > > __NR_vfork ? i.e. the uClibc logic should not require
> > > __UCLIBC_VFORK_USES_CLONE__. it can deduce that itself by saying "if
> > > !vfork && !fork && clone".
> > I don't think !fork belongs in the test. Implementing vfork with clone
> > is better than implementing it as just a duplicate of fork. But I'm
> > not sure how having macros for this can be useful at all since,
> > whatever syscall is used to implement vfork, it has to be written in
> > asm unless it's just a duplicate of fork.
> if we've got a C-callable clone(), i think we can implement a C vfork() on top
> of that. it'd be a tail call, so the semantics of parallel stack usage should
> be the same.
> i know ia64 implements vfork() with clone(), but it does it in asm, so that
> doesn't make my case :p.
The standard libc wrapper API for the clone syscall does not return
twice. It calls a function (function pointer argument) in the new
thread/process. This makes it useless for implementing vfork. In
theory it could be designed to return in the child as well if the
called function returns, but I think the usual behavior is for it to
call SYS_exit (exit thread) in that case..
> > (Providing returns-twice
> > semantics in the same memory space is not possible without asm, except
> > perhaps on some oddball architectures where the return address is
> > stored in a register
> i don't think storing the return address in a register is that odd. a CALL in
> the Blackfin ISA stores the return address in the RETS register (return from
> subroutine) and it's up to the callee to save it if need be (via manual stack
> push or the LINK insn). makes leaf functions faster since there's no touching
> of the stack at all (assuming the code can fit in the scratch registers).
It's not odd in itself; it's combining it with the latter that's odd.
> > and the compiler chooses not to use the stack to
> > store anything in the syscall wrapper function...
> i think that's the point of INLINE_SYSCALL() vs INTERNAL_SYSCALL(). the
> latter expands into inline asm that only does the syscall and doesn't touch
> the stack.
Still the surrounding function could have touched the stack. For
instance, even if the return address is stored in a register, the
compiler might decide to save that on the stack, use the return
address register for whatever random use it wants, and then restore it
from the stack later.
This *probably* won't happen as long as the function is a leaf
function, but the compiler is free to do crazy things. With -Os it
might even (in the future) combine common code (e.g. syscall setup
code) in two separate functions into code that's called from both.
> > and relying on that
> > is very unsafe since the compiler's behavior could change.)
> pray you don't look at _fork_parent() in libc/unistd/daemon.c then :p
Is that a dare? :-)
More information about the uClibc