Using the Clone() System Call

November 8th, 2000 by Joey Bernard in

Linux has introduced a new call, clone(), which allows a new level of process context creation.
Your rating: None Average: 3.8 (4 votes)

Low-level C programming has always been seen as the arena of the "guru". In my upper level operating systems course, the professor thought this was an idea that should be wiped from our minds. To this end, we had quite a few programming assignments that pushed us into totally new territories. One of these assignments was to research and use the clone() system call provided by Linux. Finding information on the low-level system calls provided by Linux was no easy task. Hopefully, this article will save any other budding guru-wannabees some time and trouble.

C programmers in the UNIX world have long used the fork() system call. This call is the basis of multiprocessing, as this is how new processes are created. Actually, for most systems, this is the only way to create a new process. Linux has introduced a new call, clone(), which allows a new level of process context creation.

Processes come in two basic flavours, heavy-weight and light-weight. Heavy-weight processes are those that you normally think of when you run a program. They contain their own address space and program execution context (see Figure 1). Light-weight processes are normally thought of as threads. These light-weight processes share the address space of the parent, and only contain some subset of the context elements (see Figure 2).

Before looking at the clone() system call, I'll begin with a quick review of fork. This system call, along with the class of exec system calls (i.e., execl(), execlp(), execv(), execvp()) is actually the way your shell executes programs given on the command line. A simple example of using fork() is given in Listing 1. The parent opens a file, assigns a value to a variable and forks a child. The child then tries to change the variable and close the file. After exiting, the parent wakes up and checks to see what the variable is and whether the file is open.

Listing 1

As you can see, the child is in a totally new address space. Within this address space, the child process receives a copy of everything the parent had at the point of forking. (This isn't exactly true in Linux. The child only receives a new copy of a memory page when it tries to make a change to something in that page. Until then, it simply uses the parent's copy. This is called copy-on-write memory management.) Changes to this copy do not affect the parent. When the child tries to change the value of the variable, the parent doesn't see this change.

Listing 2

How would you write a similar program using the clone() system call? Listing 2 gives a very basic program that looks like it copies the behaviour of the program using fork(). The most obvious difference at this stage is the fact that the clone() system call leaves all memory management up to the programmer. The first thing to be done is allocating space for the stack of the new child thread with malloc(). Once this is done, the clone() call is issued to begin a new context of execution, starting at the beginning of the given function. The general signature of this system call is

int __clone(int (*fn) (void *arg), void *child_stack, int flags, void *args)

As you can see, there are several parameters to prepare. The first parameter is a pointer to a function which returns an integer. In C, function names are pointers to functions, so this is easily taken care of. The second parameter is a pointer to the stack space that was set up for the child. You will have to decide how much space is required for the operations the child process will perform. The last parameter is a pointer to the arguments that will pass to the function that the child process will execute. In this case, that is a null pointer, since we aren't passing any arguments to the function.

The third parameter deserves special attention. This is where you can designate the flags which will define how much of the process context will be shared between the child and the parent. As in most C functions, multiple flags are simply read together. The flags available to the clone call are:

CLONE_VM - share memoryCLONE_FILES - share file descriptorsCLONE_SIGHAND - share signal handlersCLONE_VFORK - allow child to signal parent on exitCLONE_PID - share PID (not implemented yet)CLONE_FS - share filesystem

You can see that we've set up our sample program with CLONE_VM and CLONE_FILES. Looking at the output of the program, you can see that the child process will share the address space and file descriptor table with its parent. Any changes made by one process are now visible to the other. If the exact behaviour of fork() was required, all that needs to be changed is which flags are set. This way, you get to choose the exact level of sharing your program will use.

There are a few caveats I should mention in using this system call. Several functions, such as printf(), which are not thread-safe when used with clone(). These functions assume the kind of wrapping that occurs when using thread libraries, like linuxthreads. If you are experimenting with a program and run into segfaults or coredumps, this would be a likely place to look to start your troubleshooting. A possible solution would be to use lower level system calls, such as write() instead of printf(). Also, you should compile programs using the -static switch.

I am in debt to the good folks at Red Hat for pointing out some pitfalls while I stumbled my way through this article. Any errors in this article are entirely the fault of the author, and I would appreciate any corrections that you think should be made.

About the Author

Joey Bernard is a self-described uber-geek. He has one degree in physics and is working on a second degree in computer science. He hopes to become a fully ordained priest of the Church of Tux. All donations will be accepted.

__________________________


Special Magazine Offer -- Free Gift with Subscription
Receive a free digital copy of Linux Journal's System Administration Special Edition as well as instant online access to current and past issues. CLICK HERE for offer

Linux Journal: delivering readers the advice and inspiration they need to get the most out of their Linux systems since 1994.

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
Jayashree K J's picture

I think when we use clone()

On May 31st, 2006 Jayashree K J (not verified) says:

I think when we use clone() , it is a wrapper in C-library. Then after calling this wrapper , it in turn calls the actual clone(2) system call. If this is true then you have to mention it properly.
Looking for ur future & early updations, I remain.

Jayashree K J.
Bangalore ( NTPL ).
31st May, 2006.

Anonymous's picture

How can Joey Bernard will be

On March 19th, 2006 Anonymous (not verified) says:

How can Joey Bernard will be able to become a fully ordained priest of the Church of Tux, because his current profession is as a computer scientist ???????

Anonymous's picture

How can Joey Bernard will be

On March 19th, 2006 Anonymous (not verified) says:

How can Joey Bernard will be able to become a fully ordained priest of the Church of Tux, because his current profession is as a computer scientist ???????

Anonymous's picture

Re: Using the Clone() System Call

On August 31st, 2004 Anonymous says:

WOW! i have been looking for manual for clone for weeeks!!! its been driving me up the wall!!!!!!!!!!!!!!!!!!! thankyou so much!!!

Leon

sathish's picture

great article.

On September 1st, 2008 sathish (not verified) says:

truely a good article.

IN-B3's picture

Herr Fähnders, hier ist doch

On November 16th, 2004 IN-B3 (not verified) says:

Herr Fähnders, hier ist doch alles auf Englisch! :(((((

Translator's picture

Hier ist die Uebersetzung:

On November 22nd, 2004 Translator (not verified) says:

Hier ist die Uebersetzung:

http://babelfish.altavista.com/babelfish/trurl_pagecontent?url=http%3A%2F%2Fwww.linuxjournal.com%2Fnode%2F5211&lp=en_de

Viel Spass beim Lesen

joeybernard's picture

Re: Using the Clone() System Call

On February 26th, 2004 joeybernard (not verified) says:

I've come back from the proverbial grave. While googling myself, I came across this verrry old article I had written. With more experience under my belt, I realize I was very stupid in parts of this article. I will be posting a link to an updated version here in the next few weeks if anyone who finds this article wants a corrected version.

Anonymous's picture

Re: Using the Clone() System Call

On October 11th, 2004 Anonymous says:

Please do post an updated version. I found this article very helpful.

Anonymous's picture

Re: Using the Clone() System Call

On March 19th, 2004 Anonymous says:

Hi
Kindly send me updated link
Please do the necessary changes u r mentioning

also can u mention some link i could use for clone()

I am a university student
Thanks
Vipul

u03138@cs.unipune.ernet.in

Anonymous's picture

Re: Using the Clone() System Call

On September 17th, 2003 Anonymous says:

I was wondering why in the source code (listing 2) do you use a void **, when void * could very well be used for the child stack pointer

Rohit

Anonymous's picture

Hey, the stack grows downwards!

On October 28th, 2002 Anonymous says:

Hi,

I'm Pablo, a humble reader from Argentina.

I found your article very interesting, however I couldn't run the code from figure 2. I did compiled it, but the execution of the clone call, lead to a segmentation fault.

I took a look at the clone's man page and it said that the you should pass a pointer to the stack pointer of the task, not the beginning of the stack.

So, as the stack decreases, and it's empty when the thread begins, the right address would not be child_stack, but child_stack + 65383.

Only that way the code runs fine.

Hope it helps.

vijay's picture

Regarding child_stack of clone

On April 29th, 2009 vijay (not verified) says:

How you are calculating as 65383.
How much should we need to allocate for malloc.
how to calculate malloc size.

Anonymous's picture

Re: Hey, the stack grows downwards!

On February 11th, 2004 Anonymous says:

Well, it worked for me. I overlooked the -static option to cc the first time and got a segmentation fault.

Anonymous's picture

Re: Hey, the stack grows downwards!

On May 11th, 2003 Anonymous says:

Using:

child_stack + 65383

still segments for me. Where does 65383
come in? 4 * 16384 -> 65536 anyhow!

child_stack + 4000

works for me i.e. address is a definitely safe
one to use.

David (djjohn@essex.ac.uk)

Anonymous's picture

Re: Hey, the stack grows downwards!

On July 8th, 2003 Anonymous says:

You should write instead:

#define CHILD_STACK_SIZE 16384

clone( child_process, child_stack + CHILD_STACK_SIZE / sizeof( void ** ), CLONE_VM | CLONE_FILES, NULL );

Which is equivalent to CHILD_STACK_SIZE / 4 on most systems.

Anonymous's picture

Re: Hey, the stack grows downwards!

On May 6th, 2003 Anonymous says:

Hi I am manjeet,

even I faced the same problem (of segmentation fault) but

couldnt get out of it even after changing the child_stack pointer ...

Chupacabra's picture

Re: Using the Clone() System Call

On October 16th, 2001 Chupacabra (not verified) says:

I am Chupacabra! Fear my use of the Clone() System Call!

CNN.com

Post new comment

Please note that comments may not appear immediately, so there is no need to repost your comment.
The content of this field is kept private and will not be shown publicly.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <pre> <ul> <ol> <li> <dl> <dt> <dd> <i> <b>
  • Lines and paragraphs break automatically.

More information about formatting options

Newsletter

Each week Linux Journal editors will tell you what's hot in the world of Linux. You will receive late breaking news, technical tips and tricks, and links to in-depth stories featured on www.linuxjournal.com.
Sign up for our Email Newsletter

Tech Tip Videos

From the Magazine

December 2009, #188

If last month's Infrastrucuture issue was too "big" for you then try on this month's Embedded issue. Find out how to use Player for programming mobile robots, build a humidity controller for your root cellar, find out how to reduce the boot time of your embedded system, and if you're new to embedded systems find out the basics that go into one. You can also read about the Beagle Board, the Mesh Potato and a spate of other interestingly named items. And along with our regular columns don't miss our new monthly column: Economy Size Geek.







Read this issue