On 7/15/19 9:26 AM, Florian Weimer wrote:
* Eric Blake:
> On 7/14/19 12:23 AM, Florian Weimer wrote:
>> * Eric Blake:
>>
>>> Does anyone know if glibc guarantees that opendir/readdir in between
>>> multi-threaded fork() and exec() is safe, even though POSIX does not
>>> guarantee that safety in general?
>>
>> glibc supports malloc after multi-threaded fork as an extension (or as
>> a bug, because it makes malloc not async-signal-safe).
>
> It's not a bug for glibc to provide guarantees above what POSIX
> requires, but IS a bug for applications to depend on those guarantees
> without realizing they are non-portable.
It's a bug because it makes malloc not async-signal-safe (as required by
POSIX) in our current implementation of malloc.
Huh? malloc() is NOT required by POSIX to be async-signal-safe (it is
NOT in the list at
https://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html...
2.4.3 Signal Actions). POSIX allows for malloc() to be made
async-signal-safe ("Implementations may make other interfaces
async-signal-safe.") but does not require it; therefore, a
strictly-compliant POSIX application CANNOT call malloc() from inside a
signal handler, or after fork()ing from a multi-threaded app but prior
to exec(), because the signal or the fork may have interrupted another
use of malloc(), where the nested malloc() deadlocks trying to obtain
the resource held by the interrupted malloc(). But if glibc has ways to
guarantee that one malloc() can be interrupted by a signal or by a
multi-threaded fork, and still have the second re-entrant usage from
that interrupting context that won't deadlock, then glibc is providing a
stronger guarantee than what POSIX requires. Anything that has to
obtain a mutex is notoriously difficult to make async-signal-safe, which
is why POSIX does not make the requirement of malloc(), or in turn of
anything like opendir() that might use malloc() under the hood.
I don't get what you say will make malloc() non-async-signal-safe, since
POSIX does not require that was in the first place. I am, however,
stating that glibc might be willing to provide that additional guarantee
(maybe for just opendir(), rather than malloc()) even though relying on
that aspect of glibc means your application is no longer strictly
compliant, but will only work on glibc. But knowing what glibc
guarantees even when POSIX does not determines what we can do under
#ifdef __linux__ that we otherwise cannot portably do for risk of deadlock.
--
Eric Blake, Principal Software Engineer
Red Hat, Inc. +1-919-301-3226
Virtualization:
qemu.org |
libvirt.org