Skip to main content
Emphasize that the real clone() system call is different from the man-page-clone()
Source Link
user732
user732

It appears that there's two clone() things floating around in Linux 2.6

There's a system call:

int clone(int (*fn)(void *), void *child_stack,
          int flags, void *arg, ...
          /* pid_t *ptid, struct user_desc *tls, pid_t *ctid */ );

This is the "clone()" described by doing man 2 clone.

If you read that man page close enough, you will see this:

It is actually a library function layered on top of the
underlying clone() system call.

Apparently, you're supposed to implement threading using the "library function" layered on the confusingly identically named system call.

I wrote a short program:

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int
main(int ac, char **av)
{
    pid_t cpid;
    switch (cpid = fork()) {
    case 0:   // Child process
        break;
    case -1:  // Error
        break;
    default:  // parent process
        break;
    }
    return 0;
}

Compiled it with: c99 -Wall -Wextra, and ran it under strace -f to see what system calls forking actually do. I got this out of strace on a Linux 2.6.18 machine (x86_64 CPU):

20097 clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x2b4ee9213770) = 20098
20097 exit_group(0)                     = ?
20098 exit_group(0)

No "fork" call appears in the strace output. The clone() call that shows up in the strace output has very different arguments from the man-page-clone. child_stack=0 as the first argument is different than int (*fn)(void *).

It appears that the fork(2) system call is implemented in terms of the real clone(), just like the "library function" clone() is implemented. The real clone() has a different set of arguments from the man-page-clone.

Simplistically, both of your apparently contradictory statements about fork() and clone() are correct. The "clone" involved is different, though.

It appears that there's two clone() things floating around in Linux 2.6

There's a system call:

int clone(int (*fn)(void *), void *child_stack,
          int flags, void *arg, ...
          /* pid_t *ptid, struct user_desc *tls, pid_t *ctid */ );

This is the "clone()" described by doing man 2 clone.

If you read that man page close enough, you will see this:

It is actually a library function layered on top of the
underlying clone() system call.

Apparently, you're supposed to implement threading using the "library function" layered on the confusingly identically named system call.

I wrote a short program:

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int
main(int ac, char **av)
{
    pid_t cpid;
    switch (cpid = fork()) {
    case 0:   // Child process
        break;
    case -1:  // Error
        break;
    default:  // parent process
        break;
    }
    return 0;
}

Compiled it with: c99 -Wall -Wextra, and ran it under strace -f to see what system calls forking actually do. I got this out of strace on a Linux 2.6.18 machine (x86_64 CPU):

20097 clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x2b4ee9213770) = 20098
20097 exit_group(0)                     = ?
20098 exit_group(0)

No "fork" call appears in the strace output.

It appears that the fork(2) system call is implemented in terms of the real clone(), just like the "library function" clone() is implemented.

Simplistically, both of your apparently contradictory statements about fork() and clone() are correct. The "clone" involved is different, though.

It appears that there's two clone() things floating around in Linux 2.6

There's a system call:

int clone(int (*fn)(void *), void *child_stack,
          int flags, void *arg, ...
          /* pid_t *ptid, struct user_desc *tls, pid_t *ctid */ );

This is the "clone()" described by doing man 2 clone.

If you read that man page close enough, you will see this:

It is actually a library function layered on top of the
underlying clone() system call.

Apparently, you're supposed to implement threading using the "library function" layered on the confusingly identically named system call.

I wrote a short program:

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int
main(int ac, char **av)
{
    pid_t cpid;
    switch (cpid = fork()) {
    case 0:   // Child process
        break;
    case -1:  // Error
        break;
    default:  // parent process
        break;
    }
    return 0;
}

Compiled it with: c99 -Wall -Wextra, and ran it under strace -f to see what system calls forking actually do. I got this out of strace on a Linux 2.6.18 machine (x86_64 CPU):

20097 clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x2b4ee9213770) = 20098
20097 exit_group(0)                     = ?
20098 exit_group(0)

No "fork" call appears in the strace output. The clone() call that shows up in the strace output has very different arguments from the man-page-clone. child_stack=0 as the first argument is different than int (*fn)(void *).

It appears that the fork(2) system call is implemented in terms of the real clone(), just like the "library function" clone() is implemented. The real clone() has a different set of arguments from the man-page-clone.

Simplistically, both of your apparently contradictory statements about fork() and clone() are correct. The "clone" involved is different, though.

Source Link
user732
user732

It appears that there's two clone() things floating around in Linux 2.6

There's a system call:

int clone(int (*fn)(void *), void *child_stack,
          int flags, void *arg, ...
          /* pid_t *ptid, struct user_desc *tls, pid_t *ctid */ );

This is the "clone()" described by doing man 2 clone.

If you read that man page close enough, you will see this:

It is actually a library function layered on top of the
underlying clone() system call.

Apparently, you're supposed to implement threading using the "library function" layered on the confusingly identically named system call.

I wrote a short program:

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int
main(int ac, char **av)
{
    pid_t cpid;
    switch (cpid = fork()) {
    case 0:   // Child process
        break;
    case -1:  // Error
        break;
    default:  // parent process
        break;
    }
    return 0;
}

Compiled it with: c99 -Wall -Wextra, and ran it under strace -f to see what system calls forking actually do. I got this out of strace on a Linux 2.6.18 machine (x86_64 CPU):

20097 clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x2b4ee9213770) = 20098
20097 exit_group(0)                     = ?
20098 exit_group(0)

No "fork" call appears in the strace output.

It appears that the fork(2) system call is implemented in terms of the real clone(), just like the "library function" clone() is implemented.

Simplistically, both of your apparently contradictory statements about fork() and clone() are correct. The "clone" involved is different, though.