Austin Group Defect Tracker

Aardvark Mark IV

Viewing Issue Simple Details Jump to Notes ] Issue History ] Print ]
ID Category Severity Type Date Submitted Last Update
0000851 [1003.1(2013)/Issue7+TC1] System Interfaces Comment Omission 2014-06-26 23:34 2022-07-28 15:54
Reporter dancol View Status public  
Assigned To
Priority normal Resolution Accepted As Marked  
Status Resolved  
Name Daniel Colascione
User Reference
Section (section number or name, can be interface name)
Page Number (page or range of pages)
Line Number (Line or range of lines)
Interp Status ---
Final Accepted Text Note: 0005915
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 tc3-2008
Attached Files

- Relationships
related to 0000858Closed highlight the dangers of using pthread_atfork() 

-  Notes
eblake (manager)
2014-06-27 01:09

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?
geoffclare (manager)
2014-06-27 09:32
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]

dalias (reporter)
2014-06-27 14:43

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.
eblake (manager)
2014-07-10 16:07

Is there existing practice for unregistering pthread_atfork() callbacks? Also, should we add the ability to unregister an atexit() callback?
joerg (reporter)
2014-07-17 15:08

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.
dalias (reporter)
2014-07-17 16:18

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.
geoffclare (manager)
2022-07-26 11:12

The current (2016/2018) standard has this in the pthread_atfork() FUTURE DIRECTIONS:
The pthread_atfork() function may be formally deprecated (for example, by shading it OB) in a future version of this standard.

It does not seem reasonable to place additional requirements on implementations for a function that is planned to be removed from the standard at some point. So I suggest we should go ahead and shade the function OB in Issue 8 and just document the library unloading problem in APPLICATION USAGE (or RATIONALE).
geoffclare (manager)
2022-07-28 15:37

On 2018 edition page 315 line 10683 section <pthread.h> add OB shading to pthread_atfork().

On 2018 edition page 1560 line 51088-51090 add OB shading to pthread_atfork() SYNOPSIS.

On 2018 edition page 1562 line 51179 add to pthread_atfork() RATIONALE:
An additional problem arises when pthread_atfork() is called to register a function in a library that was loaded using dlopen(). If the library is unloaded using dlclose(), and the implementation of dlclose() does not unregister the function, then when fork() tries to call it the result will be undefined behavior. Some implementations of dlclose() do unregister pthread_atfork() handlers, but this cannot be relied upon by portable applications. The standard provides no portable method for unregistering a function installed as a handler via pthread_atfork().

On 2018 edition page 1562 line 51181 change pthread_atfork() FUTURE DIRECTIONS to:
The pthread_atfork( ) function may be removed in a future version of this standard.

- Issue History
Date Modified Username Field Change
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
2022-07-26 11:12 geoffclare Note Added: 0005912
2022-07-28 15:37 geoffclare Note Added: 0005915
2022-07-28 15:38 geoffclare Interp Status => ---
2022-07-28 15:38 geoffclare Final Accepted Text => Note: 0005915
2022-07-28 15:38 geoffclare Status New => Resolved
2022-07-28 15:38 geoffclare Resolution Open => Accepted As Marked
2022-07-28 15:39 geoffclare Tag Attached: tc3-2008
2022-07-28 15:54 eblake Relationship added related to 0000858

Mantis 1.1.6[^]
Copyright © 2000 - 2008 Mantis Group
Powered by Mantis Bugtracker