Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 17 Aug 2012 00:39:33 +0200
From:      Jilles Tjoelker <jilles@stack.nl>
To:        Konstantin Belousov <kostikbel@gmail.com>
Cc:        freebsd-hackers@freebsd.org, davidxu@freebsd.org
Subject:   Re: system() using vfork() or posix_spawn() and libthr
Message-ID:  <20120816223933.GA19925@stack.nl>
In-Reply-To: <20120816114426.GR5883@deviant.kiev.zoral.com.ua>
References:  <5029D727.2090105@freebsd.org> <20120814081830.GA5883@deviant.kiev.zoral.com.ua> <502A1788.9090702@freebsd.org> <20120814094111.GB5883@deviant.kiev.zoral.com.ua> <502A6B7A.6070504@gmail.com> <20120814210911.GA90640@stack.nl> <502AE1D4.4060308@gmail.com> <20120815174942.GN5883@deviant.kiev.zoral.com.ua> <502C3D8B.4060008@gmail.com> <20120816114426.GR5883@deviant.kiev.zoral.com.ua>

next in thread | previous in thread | raw e-mail | index | archive | help
On Thu, Aug 16, 2012 at 02:44:26PM +0300, Konstantin Belousov wrote:
> My point is that the fact that fork() is called from dynamic context
> that was identified as the signal handler does not mean anything.
> It can be mis-identified for many reasons, which both me and you
> tried to partially enumerate above.

> The really important thing is the atomicity of the current context,
> e.g. synchronous SIGSEGV caused by a language runtime GC is very
> much safe place to call atfork handlers, since runtimes usually cause
> signal generations only at the safe place.

> I do not think that such approach as you described can be completed,
> the _Fork() seems the only robust way.

Agreed, that way (detecting signal handler) lies madness.

If need be, _Fork() is easily implemented and used.

> BTW, returning to Jilles proposal, can we call vfork() only for
> single-threaded parent ? I think it gives good boost for single-threaded
> case, and also eliminates the concerns of non-safety.

This would probably fix the safety issues but at a price. There is a
correlation between processes so large that they benefit greatly from
vfork and threaded processes.

On the other hand, I think direct calls to vfork() in applications are
risky and it may not be possible to support them safely in all
circumstances. However, if libc is calling vfork() such as via popen(),
system() or posix_spawn(), it should be possible even in a
multi-threaded process. In that case, the rtld and libthr problems can
be avoided by using aliases with hidden visibility for all functions the
vforked child needs to call (or any other method that prevents
interposition and hard-codes a displacement into libc.so).

There may still be a problem in programs that install signal handlers
because the set of async-signal-safe functions is larger than what can
be done in a vforked child. Userland can avoid this by masking affected
signals before calling vfork() and resetting them to SIG_DFL before
unmasking them. This will add many syscalls if the code does not know
which signals are affected (such as libc). Alternatively, the kernel
could map caught signals to the default action for processes with
P_PPWAIT (just like it does not stop such processes because of signals
or TTY job control).

-- 
Jilles Tjoelker



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20120816223933.GA19925>