Не могу загрузить больше объекта со статическим TLS

У меня есть приложение, которое использует dlopen() загрузить дополнительные модули. Приложение и модули построены на Ubuntu 12.04 x86_64 с использованием gcc 4.6, но для архитектуры i386. Затем двоичные файлы копируются на другую машину с точно такой же ОС и работают нормально.

Однако, если они скопированы в Ubuntu 12.04 i386, то некоторые (но не все) модули не смогут загрузить следующее сообщение:

dlopen: cannot load any more object with static TLS

Я подозреваю, что это вызвано использованием __thread переменные. Однако такие переменные не используются в загруженных модулях — только в самом модуле загрузчика.

Может ли кто-нибудь предоставить дополнительную информацию, в чем может быть причина?

Я уменьшаю количество __thread переменные и их оптимизация (с -ftls-model и т.д.), мне просто интересно, почему это не работает на почти та же система.

10

Решение

Я подозреваю, что это вызвано использованием переменных __thread.

Правильный.

Однако такие переменные не используются в загруженных модулях — только в самом модуле загрузчика.

Неправильно. Вы не можете использовать __thread самостоятельно, но какую-то библиотеку вы статически связываете в свой модуль является используя их. Вы можете подтвердить это с помощью:

readelf -l /path/to/foo.so | grep TLS

в чем может быть причина?

Модуль использует -ftls-model=initial-exec, но следует использовать -ftls-model=global-dynamic, Это чаще всего происходит, когда (некоторые из) кода связаны с foo.so построен без -fPIC,

Связывание не-fPIC код в общую библиотеку невозможен x86_64, но разрешено ix86 (и приводит ко многим тонким проблемам, как эта).

Обновить:

У меня есть 1 модуль, скомпилированный без -fPIC, но я не устанавливаю tls-модель вообще, насколько я помню, значение по умолчанию не initial-exec

  • Для каждого образа ELF может быть только одна модель tls (исполняемая или разделяемая библиотека).
  • Модель TLS по умолчанию initial-exec для не-fPIC код.

Отсюда следует, что если вы связываете даже один не-fPIC объект, который использует __thread в foo.so, затем foo.so получает initial-exec за все его TLS.

Так почему же это вызывает проблемы — потому что если используется initial-exec, то количество переменных tls ограничено (потому что они не выделяются динамически)?

Правильный.

11

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]