(original) (raw)
My thinking on vfork/clone was affected by:
---
�the solaris man page says
http://docs.sun.com/app/docs/doc/816-5167/vfork-2?a=view
The use of vfork() in multithreaded applications,
however, is unsafe due to race conditons
that can cause the child process to become deadlocked and consequently
block both the child and parent process from execution indefinitely.
(In fact, I'm still afraid that one of those race conditions will kill the vfork option
even on Linux)
That man page also says,
The vfork() function is deprecated. Its sole legitimate use as a prelude to an immediate call to a function from the exec family can be achieved safely by posix_spawn(3C) or posix_spawnp(3C).
But...posix_spawn doesn't give you any way to delete *all* file descriptors
and if you try to collect them before spawning, there is a race in a multithreaded program.
(Aside: I also wonder why glibc's implementation of posix_spawn avoids using vfork
if there are file actions specified)
---
Linux clone has avoided vfork's bad press, and has occasionally been
described as "elegant".� For a while I believed that clone() was the only
system call that created new processes, and that vfork() was just an
inflexible special case of clone(), and on ia64 that appears to be true,
but on x86 clone(), fork() and vfork() are separate system calls,
and glibc has different gobs of assembly code around each.
In particular, glibc's clone fiddles with TIDs even when CLONE_THREAD
is not specified, while vfork never does.� That feels like a bug.
~/src/glibc-2.10.1 $ for x in vfork clone; do echo --- x−−−;find−namex --- ; find -name x−−−;find−namex.S | xargs grep -l -i tid; done
--- vfork ---
--- clone ---
./sysdeps/unix/sysv/linux/s390/s390-64/clone.S
./sysdeps/unix/sysv/linux/s390/s390-32/clone.S
./sysdeps/unix/sysv/linux/x86_64/clone.S
./sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S
./sysdeps/unix/sysv/linux/powerpc/powerpc32/clone.S
./sysdeps/unix/sysv/linux/i386/clone.S
./sysdeps/unix/sysv/linux/sh/clone.S
./sysdeps/unix/sysv/linux/sparc/sparc32/clone.S
./sysdeps/unix/sysv/linux/sparc/sparc64/clone.S
I'm still hoping we can fix something in glibc.
Martin
I am a bit surprised that you see that failure mode, and it's possible it
indicates an actual bug in pthread_getattr_np that you could find some
other (kosher) way to provoke. �But it is generally true that if you use
-lpthread then attempting using clone() with CLONE_VM on your own at all is
not a reasonable thing to expect to work.
I get the impression that all you are trying to do is spawn an exec'd
process in some fashion where you need to do a little bit more work on the
child side than just exec alone, but not much. �This is exactly the case
that vfork exists to optimize, and I am rather shocked and amazed that you
should ever have considered anything else before just using vfork. �Aside
from the portability issues, that is just the simplest and easiest option
by far.
I am bemused that you cite "dire warnings" about use of vfork, but are less
dissuaded from something so deep in the bowels of Linux implementation, so
under-specified, and so hard to use as clone. �Perhaps you didn't notice
any comparable dire warnings about clone because it never occurred to
anyone that someone who needed to be warned would ever stumble into a
thicket normally so hidden from view, and so obviously fraught with peril,
as clone. �The vfork caveats are suitably dire indeed--strongly indicating
that the only proper use of vfork is precisely the use you need it for--but
these same warnings have been posted and remained consistent since the
invention of vfork in 4.2BSD something like 25 years ago.
Thanks,
Roland