After running ltrace -S on two programs that were compiled by gcc (version 5.4.0), one that calls vfork() and one that calls fork(), I find that vfork() calls SYS_vfork whilst fork() calls SYS_clone. I could not find any information about this specific behavior anywhere (some sources say each of fork(), vfork() and clone() are implemented by the correspondingly named sys_ call, whilst other sources say all three calls are implemented using sys_clone).
Source code:
#include<stdio.h>
main()
{
int pid;
pid=vfork();
}
Output from ltrace -S:
...
__libc_start_main([some stuff here] <unfinished ...>
vfork([more stuff] <unfinished ...>
SYS_vfork([more stuff])
--- SIGCHLD (Child exited) ---
Is there a reason libc uses SYS_vfork for vfork()
but doesn't use SYS_fork for fork()?
I’ve read Thomas Nyman’s answer to
Which file in kernel specifies fork(), vfork()…
to use sys_clone() system call, which says:
vfork()in turn is implemented via a separateCLONE_VFORKflag, which will cause the parent process to sleep until the child process wakes it via a signal. The child will be the sole thread of execution in the parent's namespace, until it callsexec()or exits. The child is not allowed to write to the memory. The correspondingclone()call could be as follows:
clone(CLONE_VFORK | CLONE_VM | SIGCHLD, 0)
This seems to be at odds with what I've observed of the output of ltrace -S.
Did I mess something up or did the glibc writers deliberately choose to implement vfork() using SYS_vfork instead of SYS_clone for a reason? Is this considered something that could change at any time or can we rely on it?