From owner-freebsd-hackers@FreeBSD.ORG Thu Aug 16 11:44:32 2012 Return-Path: Delivered-To: freebsd-hackers@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 8E2F9106564A; Thu, 16 Aug 2012 11:44:32 +0000 (UTC) (envelope-from kostikbel@gmail.com) Received: from mail.zoral.com.ua (mx0.zoral.com.ua [91.193.166.200]) by mx1.freebsd.org (Postfix) with ESMTP id 0CA8B8FC17; Thu, 16 Aug 2012 11:44:31 +0000 (UTC) Received: from skuns.kiev.zoral.com.ua (localhost [127.0.0.1]) by mail.zoral.com.ua (8.14.2/8.14.2) with ESMTP id q7GBidri095603; Thu, 16 Aug 2012 14:44:39 +0300 (EEST) (envelope-from kostikbel@gmail.com) Received: from deviant.kiev.zoral.com.ua (kostik@localhost [127.0.0.1]) by deviant.kiev.zoral.com.ua (8.14.5/8.14.5) with ESMTP id q7GBiRw4031637; Thu, 16 Aug 2012 14:44:27 +0300 (EEST) (envelope-from kostikbel@gmail.com) Received: (from kostik@localhost) by deviant.kiev.zoral.com.ua (8.14.5/8.14.5/Submit) id q7GBiQpw031636; Thu, 16 Aug 2012 14:44:26 +0300 (EEST) (envelope-from kostikbel@gmail.com) X-Authentication-Warning: deviant.kiev.zoral.com.ua: kostik set sender to kostikbel@gmail.com using -f Date: Thu, 16 Aug 2012 14:44:26 +0300 From: Konstantin Belousov To: davidxu@freebsd.org Message-ID: <20120816114426.GR5883@deviant.kiev.zoral.com.ua> 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> Mime-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="8Bx+wEju+vH9ym24" Content-Disposition: inline In-Reply-To: <502C3D8B.4060008@gmail.com> User-Agent: Mutt/1.4.2.3i X-Virus-Scanned: clamav-milter 0.95.2 at skuns.kiev.zoral.com.ua X-Virus-Status: Clean X-Spam-Status: No, score=-4.0 required=5.0 tests=ALL_TRUSTED,AWL,BAYES_00 autolearn=ham version=3.2.5 X-Spam-Checker-Version: SpamAssassin 3.2.5 (2008-06-10) on skuns.kiev.zoral.com.ua Cc: freebsd-hackers@freebsd.org, Jilles Tjoelker Subject: Re: system() using vfork() or posix_spawn() and libthr X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 16 Aug 2012 11:44:32 -0000 --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--