This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: posix_spawn and vfork


* Adhemerval Zanella:

>> If we want to go this route, I'd suggest something like this as a
>> building block:
>> 
>>   pid_t clone_samestack (unsigned int flags, void (*action) (void *)
>>                          void *closure);
>> 
>> and it would be a fatal error if ACTION (CLOSURE) returns.  The function
>> would fail with EINVAL if FLAGS contained CLONE_VM without CLONE_VFORK.
>> 
>> Once we have that, the need for explicit stack management goes away.
>
> But would it just a shim wrapper over clone (to handle the required kABI)
> as vfork currently is or something more sane as posix_spawn to work
> correctly along libc? Also, would be just an internal interface or
> a possible extension?

I think it would make sense to start out with the thin wrapper, and then
build the safer vfork abstraction on top of that.

> Because for a clone wrapper, I think would be simpler to just make using
> clone instead by allowing it accept a null stack input.
>
> ---
>   struct wrapper_argument
>   {
>     void (*action) (void *) fn;
>     void *arg;
>   };
>
>   void wrapper (void *input)
>   {
>     struct wrapper_argument *arg = input;
>     arg->fn (arg->arg);
>     abort ();
>   }
>
>   pid_t clone_samestack (unsigned int flags, void (*action) (void *)
>                          void *closure)
>   {
>     int clone_flags = CLONE_VM | CLONE_VFORK | SIGCHLD;
> #ifndef __ia64__
>     return clone (wrapper, NULL, clone_flags,
> 		  &(struct wrapper_argument) { action, closure }));
> #else
>     return __clone2 (wrapper, NULL, sizeof stack,
>                      &(struct wrapper_argument) { action, closure }));
> #endif
>   }
>
> ---
>
> It also wouldn't require potentially another arch-specific assembly 
> implementation.

For the x86-64 and i386 implementations, it's not just about removing
the NULL check.  I think we will need different trampoline functions,
with different unwinding data.  At that point, we can just rewrite the
whole function.

> However my main issue with such interface where is reuses the stack from
> parent process is how safe this construction is.  That's why I think the
> xfork symbol, which either allocates a pre-defined stack or accepts a 
> user-define one (as for sigaltstack) should be safer and play along
> libc interfaces better (it could either share some code with posix_spawn).

I think it boils down to whether the parent thread is reliably stopped
during vfork (if it is not implemented as fork).  I have not seen any
indication so far that the blocking is unreliable in current (3.x)
kernels.

In contrast, when sizing the separate stack, you need to make educated
guesses about ld.so stack space requirements.  Ideally, you would also
add a guard page.  The new stack may need to be communicated to memory
debuggers.  And so on.  All in all, stack switching seems more risky to
me.

Thanks,
Florian


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]