On 7/15/19 12:01 PM, Florian Weimer wrote:
>>>> 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
Sorry, I mistyped. I meant to write fork. It's on the list.
Ah, that makes much more sense. In other words, the manner in which
glibc guarantees that malloc() can be called after fork() is enough to
simultaneously break the POSIX requirement that fork() can be called
from a signal handler without risking deadlock (because whatever glibc
does to make malloc safe after fork is not re-entrant enough if a signal
handler tries to fork while glibc was already in the middle of preparing
for fork).
Is it worth opening a bug against POSIX to try to strike or reduce the
requirement that fork() be async-signal safe? For a single-threaded
app, fork()ing in a signal handler might have made sense, but as POSIX
already says:
"When the application calls fork() from a signal handler and any of the
fork handlers registered by pthread_atfork() calls a function that is
not async-signal-safe, the behavior is undefined."
...
"While the fork() function is async-signal-safe, there is no way for an
implementation to determine whether the fork handlers established by
pthread_atfork() are async-signal-safe. The fork handlers may attempt to
execute portions of the implementation that are not async-signal-safe,
such as those that are protected by mutexes, leading to a deadlock
condition. It is therefore undefined for the fork handlers to execute
functions that are not async-signal-safe when fork() is called from a
signal handler."
it might be nicer if the POSIX wording were changed to require fork() to
be async-signal safe only when used in a single-threaded application
(where pthread_atfork() is not in use), or even dropped the requirement
altogether (relying on implementations to provide that additional
guarantee if they'd like, but not requiring it of all implementations).
--
Eric Blake, Principal Software Engineer
Red Hat, Inc. +1-919-301-3226
Virtualization:
qemu.org |
libvirt.org