Using the Clone() System Call
November 8th, 2000 by Joey Bernard in
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.
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.
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.
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.
Subscribe now!
The Latest
Newsletter
Tech Tip Videos
- Jul-01-09
- Jun-29-09
Recently Popular
From the Magazine
July 2009, #183
News Flash: Linux Kernel 3.0 to include an on-the-go Expresso machine interface! Ok, maybe not, but Linux is definitely going mobile, from phones to e-readers. Find out more inside about Android, the Kindle 2, the Western Digital MyBook II, The Bug, and Indamixx (a portable recording studio). And if you've gone mobile and you been wanting more Emacs in your life then check out Conkeror.
To compliment the mobile we've got the stationary: parsing command line options with getopt, checking your Ruby code with metric_fu, and building a secure Squid proxy. How is this stationary you ask? What can we say? It's not. We just wanted to see if anybody actually read this part of the page :) .
All this and more, and all you have to do is get your hot sweaty hands on the latest copy of Linux Journal.
Delicious
Digg
StumbleUpon
Reddit
Facebook








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.
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 ???????
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 ???????
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
great article.
On September 1st, 2008 sathish (not verified) says:
truely a good article.
Herr Fähnders, hier ist doch
On November 16th, 2004 IN-B3 (not verified) says:
Herr Fähnders, hier ist doch alles auf Englisch! :(((((
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
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.
Re: Using the Clone() System Call
On October 11th, 2004 Anonymous says:
Please do post an updated version. I found this article very helpful.
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
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
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.
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.
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.
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)
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.
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 ...
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