Ответ 1
Я подозреваю, что это вызвано использованием переменных __thread.
Правильно.
Однако такие переменные не используются в загруженных модулях - только в самом модуле загрузчика.
Неправильно. Вы не можете использовать __thread
самостоятельно, но какая-то библиотека, которую вы статически связываете с модулем, использует их. Вы можете подтвердить это с помощью:
readelf -l /path/to/foo.so | grep TLS
В чем может быть причина?
Модуль использует -ftls-model=initial-exec
, но должен использовать -ftls-model=global-dynamic
. Это чаще всего происходит, когда (некоторые из) код, связанный с foo.so
, строится без -fPIC
.
Связывание кода non -fPIC
в общую библиотеку невозможно на x86_64
, но разрешено на ix86
(и приводит ко многим тонким проблемам, как этот).
Update:
У меня есть 1 модуль, скомпилированный без -fpIC, но я не устанавливаю tls-model вообще, насколько я помню, значение по умолчанию не является initial-exec
- Для каждого изображения ELF (исполняемая или разделяемая библиотека) может быть только одна модель tls.
- Модель TLS по умолчанию равна
initial-exec
для кода не-fPIC
.
Из этого следует, что если вы связываете хотя бы один объект -fPIC
, который использует __thread
в foo.so
, то foo.so
получает initial-exec
для всех своих TLS.
Так почему это вызывает проблемы - потому что, если используется initial-exec, количество переменных tls ограничено (потому что они не динамически распределены)?
Правильно.