Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 16 Aug 2012 14:44:26 +0300
From:      Konstantin Belousov <kostikbel@gmail.com>
To:        davidxu@freebsd.org
Cc:        freebsd-hackers@freebsd.org, Jilles Tjoelker <jilles@stack.nl>
Subject:   Re: system() using vfork() or posix_spawn() and libthr
Message-ID:  <20120816114426.GR5883@deviant.kiev.zoral.com.ua>
In-Reply-To: <502C3D8B.4060008@gmail.com>
References:  <20120809105648.GA79814@stack.nl> <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>

next in thread | previous in thread | raw e-mail | index | archive | help

--8Bx+wEju+vH9ym24
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

On Thu, Aug 16, 2012 at 08:23:39AM +0800, David Xu wrote:
> On 2012/08/16 01:49, Konstantin Belousov wrote:
> >On Wed, Aug 15, 2012 at 07:40:04AM +0800, David Xu wrote:
> >>On 2012/08/15 05:09, Jilles Tjoelker wrote:
> >>>On Tue, Aug 14, 2012 at 11:15:06PM +0800, David Xu wrote:
> >>>>But in real word, pthread atfork handlers are not async-signal safe,
> >>>>they mostly do mutex locking and unlocking to keep consistent state,
> >>>>mutex is not async-signal safe.
> >>>>The malloc prefork and postfork handlers happen to work because I have
> >>>>some hacking code in library for malloc locks. Otherwise, you even
> >>>>can not use fork() in signal handler.
> >>>This problem was also reported to the Austin Group at
> >>>http://austingroupbugs.net/view.php?id=3D62
> >>>
> >>>Atfork handlers are inherently async-signal-unsafe.
> >>>
> >>>An interpretation was issued suggesting to remove fork() from the list
> >>>of async-signal-safe functions and add a new async-signal-safe function
> >>>_Fork() which does not call the atfork handlers.
> >>>
> >>>This change will however not be in POSIX.1-2008 TC1 but only in the ne=
xt
> >>>issue (SUSv5).
> >>>
> >>>A slightly earlier report http://austingroupbugs.net/view.php?id=3D18 =
just
> >>>requested the _Fork() function because an existing application
> >>>deadlocked when calling fork() from a signal handler.
> >>>
> >>Thanks, although SUSv5 will have _Fork(), but application will not catc=
h=20
> >>up.
> >>
> >>One solution for this problem is thread library does not execute
> >>atfork handler when fork() is called from signal handler, but it
> >>requires some work to be done in thread library's signal wrapper,
> >>for example, set a flag that the thread is executing signal handler,
> >>but siglongjmp can mess the flag, so I have to tweak sigsetjmp and
> >>siglongjmp to save/restore the flag, I have such a patch: it fetches
> >>target stack pointer stored in jmpbuf, and compare it with top most
> >>stack pointer when a first signal was delivered to the thread, if the
> >>target stack pointer is larger than the top most stack pointer, the
> >>flag is cleared.
> >>
> >I do not understand how this interacts with altstacks.
> >
> >Also, there are longjmp()s implemented outside the base, e.g. in the
> >libunwind, which cannot be fixed this way.
> >
> >Also, there are language runtimes that relies heavily on the (synchronou=
s)
> >signals and which use their internal analogues of the stack unwinding,
> >which again be broken by such approach.
> My patch is very experimental. There are setcontext and getcontext
> which also can break it. Another solution would save a flag into
> jmpbuf or ucontext, and indicates the signal handler is executing.
> a setjmp or getcontext executed in normal context would not
> have such a flag, but if they executes in signal handler, the per-thread
> flag will be saved. but it requires lots of changes, and setcontext and
> getcontext are syscall, kernel does know such a userland flag, unless
> they are shared between kernel and userland.
>=20

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.

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.

--8Bx+wEju+vH9ym24
Content-Type: application/pgp-signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.12 (FreeBSD)

iEYEARECAAYFAlAs3RoACgkQC3+MBN1Mb4jIzwCgusnKixcw5EdhopIt8hMszX4L
KqsAoOpTByxsSGt7rQ5CkbGLz8eKHnx8
=74GS
-----END PGP SIGNATURE-----

--8Bx+wEju+vH9ym24--



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