This is the mail archive of the
libc-help@sourceware.org
mailing list for the glibc project.
Re: clone(2)
- From: vijay nag <vijunag at gmail dot com>
- To: Ángel González <keisial at gmail dot com>
- Cc: libc-help <libc-help at sourceware dot org>
- Date: Thu, 19 Dec 2013 10:44:47 +0530
- Subject: Re: clone(2)
- Authentication-results: sourceware.org; auth=none
- References: <CAKhyrx8p46xMrWROE1aifPcxF1m=_d+zGV5brunxDhyhcFgzzA at mail dot gmail dot com> <52B20396 dot 3030400 at gmail dot com>
On Thu, Dec 19, 2013 at 1:50 AM, Ángel González <keisial@gmail.com> wrote:
> TL;DR: You need to provide child_stack.
>
>
> On 18/12/13 19:14, vijay nag wrote:
>>
>> Hello,
>>
>> I want to create a new process using clone(2) system call. The
>> clone(2) is invoked the following way "clone(NULL, NULL, SIGCHLD |
>> CLONE_PARENT, NULL);" and seems to be returning EINVAL. I RTFM of
>> clone(2) which suggested me to use NULL for child_stack when creating
>> a new task. It also suggests that EINVAL is returned when child_stack
>> argument is NULL. I'm little bit confused about its usage. Can someone
>> illustrate a simple invocation of clone(2) for creating a child task ?
>
> The man page mentions two things: the clone() method provided by libc and
> the raw syscall interface which differs slightly. You are only interested in
> the first one, and it doesn't allow a NULL child_stack.
>
>
>
>> Excerpts from man for sys_clone
>>
>> "Another difference for sys_clone is that the child_stack argument may
>> be zero, in which case copy-on-write semantics ensure that the child
>> gets separate copies of stack pages when either process modifies the
>> stack. In this case, for correct operation, the CLONE_VM option should
>> not be specified."
>
> This is at the «The raw system call interface» section, and is comparing the
> clone syscall (let's call it sys_clone) to clone(). So ignore this section.
>
>
>
>> EINVAL
>>
>> Returned by clone() when a zero value is specified for child_stack.
>
>
>
> Finally, there's anothe relevant to child_stack (maybe it's missing in your
> version of the man page).
>>
>> The child_stack argument specifies the location of the stack used
>> by the child process. Since the child and calling process may share memory,
>> it is not possible for the child
>> process to execute in the same stack as the calling process. The
>> calling process must therefore set up memory space for the child stack and
>> pass a pointer to this space to
>> clone(). Stacks grow downward on all processors that run Linux
>> (except the HP PA processors), so child_stack usually points to the topmost
>> address of the memory space set up
>> for the child stack.
>
>
>
> Merry Christmas
Since I don't intend to create a separate stack for N number of cloned
children, that leaves me with the option of directly calling syscall
for __NR_clone and bypassing glibc. Of all the possible optimizations,
glibc has chosen to optimize calls to tiny getXXX() system calls. The
reason why I replaced sys_clone with glibc clone(2) was to get
consistent results from getpid() in the cloned task. Bypassing glibc
clone(2) results in window time during which getpid() returns parent's
pid till the cache gets updated. I'm left with following options to
safely call syscall for __NR_clone i.e
1) Write a wrapper for clone that does syscall for __NR_clone and
updates the cache in glibc ?
If this is a plausible approach, what is the way to invalidate the cache ?
2) Is it possible to disable NPTL optimizations for getXXX() in glibc ?