This is the mail archive of the
libc-help@sourceware.org
mailing list for the glibc project.
Re: clone(2)
- From: OndÅej BÃlka <neleai at seznam dot cz>
- To: vijay nag <vijunag at gmail dot com>
- Cc: Ángel González <keisial at gmail dot com>, libc-help <libc-help at sourceware dot org>
- Date: Thu, 19 Dec 2013 11:22:57 +0100
- 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> <CAKhyrx-NLrvbVnAZL8RMOEEVxauD8F0zZ3j=RSYYE_ASYOFWUw at mail dot gmail dot com>
On Thu, Dec 19, 2013 at 10:44:47AM +0530, vijay nag wrote:
> 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 ?
As 2) write your own getXXX that just do syscalls.