TLS and Signals

In general access to TLS is not asynchronous-siginal safe.

There are two potentially dangerous scenarios:

Secnario 1: Non-atomic initialization:

One specific case which causes problems is access to a TLS variable from a signal handling function that is part of a dynamically shared object loaded via dlopen. Such access to TLS variagles must be done via the general dynamic model (GD) and that model supports lazy initialization. If a thread is in the middle of initializing TLS, is interrupted by a signal that uses TLS, then the code in the signal handler may fault since TLS is only partially initialized.

Scenario 2: Asynchronous-signal unsafe functions called during lazy initialization:

Another case appears to be especially easily triggered via SIGPROF profiling:

Upstream discussions:

An original discussion of the issues was started by Paul Pluzhnikov from Google:

https://sourceware.org/ml/libc-alpha/2012-06/msg00335.html

The discussion has been resurrected here:

https://sourceware.org/ml/libc-alpha/2013-09/msg00563.html

Design Considerations

{{{If the signal occurs other than as the result of calling the abort or raise function, the behavior is undefined if the signal handler refers to any object with static or thread storage duration that is not a lock-free atomic object other than by assigning a value to an object declared as volatile sig_atomic_t, or the signal handler calls any function in the standard library other than the abort function, the _Exit function, the quick_exit function, or the signal function with the first argument equal to the signal number corresponding to the signal that caused the invocation of the handler. Furthermore, if such a call to the signal function results in a SIG_ERR return, the value of errno is indeterminate.252) }}}

Solution