This document proposes to prevent strictly conforming programs to use pointer values returned from certain library functions after the thread that originally called them has exited. It is related to papers N2225, N2226, N2227.
The core observation which motivates this document is that while the standard does not require to detect data races involving certain library functions, it does rule out a straightforward implementation of these library functions based on objects of thread storage duration. Returning a pointer to such objects does not work because the objects cease to exist once the thread exits.
strerror function is widely used in
thread-aware programs (which use threads and synchronization
in other ways). It is much simpler to use than
strerror_r function provided by some
implementations (whose use is further complicated by varying
prototypes between implementations).
Since reading the returned string happens after
strerror function has returned, merely
avoid data races within the function is insufficient. It
also would not address the higher-level race condition;
threads would still obtain an incorrect error message
generated by another thread.
As an alternative approach, an implementation could avoid
deallocating the object storing the error message when the
thread exits, and reuse it for a future call to
strerror function. However, that
introduces substantial complexity for a very small gain.
If an implementation does not include an unknown error
number in the result of the
and takes some precautions about changing the program's
locale, a thread-safe implementation is already possible
because it is not necessary to provide backing storage for
the result: all possible result strings are known in advance
and can be precomputed.
POSIX defines both a
strerror_l function. Both are required to be
strerror_l cannot be used with
the global locale handle, i.e., the program's locale).
There is no discussion what happens when the thread
strerror_l exits; presumably the
previously returned pointer becomes invalid, as POSIX
mentions in the context of the
The time conversion functions face a very similar issue.
Objects of thread storage duration are apparently already used in the Solaris implementation:
localtime()functions are safe to use in multithread applications because they employ thread-specific data. [Source]
However, it is unclear whether this is at the expense of making undefined subsequent pointer access after thread exit.
POSIX suggests that a thread-safe implementation of these
functions is possible, but does not mention the behavior on
thread exit as far as the returned pointer is concerned
(which it does for the
TheIn J.2 (Undefined behavior), add:
strerrorfunction returns a pointer to the string, the contents of which are locale- specific. The array pointed to shall not be modified by the program, but may be overwritten by a subsequent call to the
Execution of any of the functions that return a pointer to one of these object types may overwrite the information in any object of the same type pointed to by the value returned from any previous call to any of them and the functions are not required to avoid data races with each other. 322) The implementation shall behave as if no other library functions call these functions.In J.2 (Undefined behavior), add: