I am tracing posix_spawn source code in glibc 2.17 and glibc 2.27.
(glibc 2.17: sysdeps/posix/spawni.c)
(glibc 2.27: sysdeps/unix/sysv/linux/spawni.c)
I found glibc 2.17 uses vfork or fork depending on flags and file actions.
I guess it is due to multithread safety or race condition.
But in glibc 2.27, it only uses vfork to create a subprocess.
Why does glibc change the implementation?
Is the newer linux kernel better to protect vfork against race conditions?
vfork
is substantially more efficient for large processes than fork
because the address space does not have to be duplicated at all. Originally, there were concerns that proper cancellation handling would require the use of fork
in case of file actions present, but eventually, it was determined that the current vfork
-based implementation was adequate.
vfork
is still broken in qemu-user and Microsoft's emulation, but the bugs usually are not visible when using posix_spawn
because it does not actually use vfork
, but a vfork
-style clone
system call with a separate stack, so that even if the parent process is not properly paused, the stack in the child is not clobbered.
Some resources with background information:
vfork
emulation bug)