
* Eric Blake:
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).
It's taking all the malloc locks, so interrupting malloc is sufficient to trigger a deadlock with fork. There are a bunch of other locks as well, but the malloc locks is the most prominent one.
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:
fork is commonly used in in-process crash handlers. I suspect this is in part because it allows one to stop all other threads. I do not think this is the proper way to write crash handlers (at least not on Linux), but it's still very much current practice. I would certainly welcome a different requirement from POSIX, but then maybe POSIX does not want to act as the driver of change on our behalf like this. Thanks, Florian