NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: kern/49017: vfork does not suspend all threads



The following reply was made to PR kern/49017; it has been noted by GNATS.

From: Nico Williams <Nico.Williams%twosigma.com@localhost>
To: <gnats-bugs%netbsd.org@localhost>
Cc: 
Subject: Re: kern/49017: vfork does not suspend all threads
Date: Thu, 6 Apr 2017 15:26:53 +0000

 Robert Elz <kre%munnari.OZ.AU@localhost> wrote:
 > There's no need to restrict vfork() children to async signal safe operations
 > (the process limiting itself that way certainly won't hurt it, but it is
 
 It is certainly necessary to restrict what a fork() child can do when the
 parent process has built up a lot of state...  If the fork() parent has built
 very little state, if the fork() call comes early in its life, then it is safe
 to do just about anything on the child-side.
 
 OTOH, if the fork() parent has built a lot of state, possibly with various
 possibly-unknown-to-it libraries, it may not be safest to call anything but
 async-signal-safe functions.  And that's why POSIX says that's what the child
 can do.
 
 (Some APIs are explicitly fork-unsafe (e.g., PKCS#11); using them on the parent
 side of fork() means that one cannot use them on the child side without
 reinitializing the library or execve()'ing.)
 
 Heck, "async-signal-safe" is a somewhat misleading concept because fork() and
 vfork() do not atomically block signals on the child side, so a number of
 async-signal-safe functions are actually very much unsafe to call in a signal
 handler without first checking that getpid() returns the expected PID.
 
 With few exceptions, the only things I ever do in a signal handler are: check
 if getpid() returns the expected PID, write to sig_atomic_t global variables,
 and/or write(2) a single byte to a pipe the other end of which is handled by an
 event loop.
 
 "Async-signal-safe" is what POSIX calls the set of functions that it thinks
 are safe to call in signal handlers and the child side of fork().  Even if it
 is too small a set, it is useful enough a concept that we can use it to talk
 about what kinds of things are safe to do on the child side of vfork().
 
 > not required) - it can do anything that the parent can do that affects only
 > its internal (userland) state, or which affects purely the proc struct
 > state in the kernel (so it can close files, or change the "close on exec"
 > state, but not other file status flags).
 
 Certainly one can make safe use of some functions outside the async-signal-safe
 set in the fork()/vfork() child sides.  It does help to have some idea of what
 might go wrong when one does that.  POSIX defines such a set in part so that
 one can write portable code without having to know much about particular OSes.
 
 Thor pointed out to me yesterday that using mutexes on the child side of
 vfork() should have the same sorts of semantics and dangers as using shared
 mutexes, so one should not categorically dismiss the use of mutexes on the
 child side of vfork().  I agree with Thor on this, though I would generally
 discourage the use of shared mutexes anyways.
 
 Nico
 -- 
 



Home | Main Index | Thread Index | Old Index