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