cforksystem-callsglibcstrace

Why is fork() accepted in strace if the actual syscall is clone()?


I am using the following command to check the number of system calls during the execution of one of my programs:

strace -e trace=<syscall> -c ./program [ARGS]

If I substitute <syscall> with fork() it returns a total of 0 calls, as it is now implemented with clone(). However, if it returns 0 all the time, why is it still accepted as a system call? Isn't it just a wrapper for the actual syscall clone()?

I would expect the strace command to return an error for trace=fork() such as:

strace: invalid system call 'fork'

I just do not understand why it is still accepted as a valid parameter if it actually is just clone(). What am I missing? Why is it still accepted in strace if the parameter only accepts system calls?

Links I checked:


Solution

  • You are confusing the C library function with the actual syscall. Since the clone syscall is more powerful and can always be used in place of fork, most C libraries have implemented the library function fork() in terms of the clone syscall. However, the fork syscall definitely still exists. This is because the kernel needs to guarantee backwards compatibility with older programs that use fork.

    Internally, in terms of kernel code, fork is implemented as a call to clone (see e.g., the code here), but it still exists. Therefore it makes sense that tools like strace still know about fork and allow you to filter for it. The only architecture I can think of where fork does not exist as a syscall is ARM64 with AArch64 ABI, which is "recent".