|Anonymous | Login||2021-12-02 13:30 UTC|
|Main | My View | View Issues | Change Log | Docs|
|Viewing Issue Simple Details|
|ID||Category||Severity||Type||Date Submitted||Last Update|
|0000851||[1003.1(2013)/Issue7+TC1] System Interfaces||Comment||Omission||2014-06-26 23:34||2014-07-17 16:18|
|Section||(section number or name, can be interface name)|
|Page Number||(page or range of pages)|
|Line Number||(Line or range of lines)|
|Final Accepted Text|
|Summary||0000851: pthread_atfork orphans handlers in unloaded shared libraries|
|Description||pthread_atfork is used to register functions to be called before and after a fork operation. The intent of the facility is to ensure that the child receives consistent copies of mutexes and other pieces of shared state. If a process loads a shared library, registers pthread_atfork handlers for that library, then unloads the library, the process will likely segfault the next time it calls fork. Some implementations automatically unregister handlers in this scenario, but there is no requirement to do so, and many implementations malfunction in the way described above.|
|Desired Action||Please either requirement dlclose to automatically unregister pthread_atfork handlers or provide an explicit interface for unregistering these handlers manually. I would prefer the explicit interface.|
|Tags||No tags attached.|
|The standard is already clear that pthread_atfork cannot usefully be used in multithreaded programs. "As explained, there is no suitable solution for functionality which requires non-atomic operations to be protected through mutexes and locks. This is why the POSIX.1 standard since the 1996 release requires that the child process after fork( ) in a multi-threaded process only calls async-signal-safe interfaces." (line 50303). Given that, is there any really reason to try and extend the requirements of an already broken-by-design interface?|
edited on: 2014-07-11 14:33
I don't think the standard currently does enough to warn application writers of the dangers of using this function. In addition to any change relating to dlclose() I would suggest making the following changes:
After line 50230 add a new paragraph:
If a fork() call in a multi-threaded process leads to a child fork handler calling any function that is not async-signal-safe, the behavior is undefined.
On line 50244 change the APPLICATION USAGE section from:
The original usage pattern envisaged for pthread_atfork() was for the prepare fork handler to lock mutexes and other locks, and for the parent and child handlers to unlock them. However, since all of the relevant unlocking functions are not async-signal-safe this usage results in undefined behavior in the child process.
On page 889 line 29741 section fork() delete:
Fork handlers may be established by means of the pthread_atfork() function in order to maintain application invariants across fork() calls.
[Update: these changes are now the subject of a separate bug: 0000858]
Regarding: "However, since all of the relevant unlocking functions are not async-signal-safe this usage results in undefined behavior in the child process."
This statement is not entirely true: sem_post is async-signal-safe. It's not clear to me whether the copy of a semaphore which exists in the child after fork is a valid argument for sem_post, but perhaps the issue should be clarified, since sem_post provides a seemingly-plausible way to use pthread_atfork while avoiding the design flaw.
|Is there existing practice for unregistering pthread_atfork() callbacks? Also, should we add the ability to unregister an atexit() callback?|
There is existing practice in Solaris to auto-unregister functions for various
callbacks in case that dlclose() has been called for a library that contains
such a callback function.
|Perhaps dlclose should be required either to unregister such handlers when unloading the library, or to refuse to unload any library for which such handlers have been registered. This would leave some flexibility with the implementation while ensuring that handlers which are no longer loaded do not get called.|
|2014-06-26 23:34||dancol||New Issue|
|2014-06-26 23:34||dancol||Name||=> Daniel Colascione|
|2014-06-26 23:34||dancol||Section||=> (section number or name, can be interface name)|
|2014-06-26 23:34||dancol||Page Number||=> (page or range of pages)|
|2014-06-26 23:34||dancol||Line Number||=> (Line or range of lines)|
|2014-06-27 01:09||eblake||Note Added: 0002286|
|2014-06-27 09:32||geoffclare||Note Added: 0002287|
|2014-06-27 14:43||dalias||Note Added: 0002291|
|2014-07-10 16:07||eblake||Note Added: 0002307|
|2014-07-11 14:33||geoffclare||Note Edited: 0002287|
|2014-07-17 15:08||joerg||Note Added: 0002309|
|2014-07-17 16:18||dalias||Note Added: 0002310|
|Mantis 1.1.6[^] Copyright © 2000 - 2008 Mantis Group|