Я сам столкнулся с этой ошибкой и, исследуя ее, наткнулся на сообщение в списке рассылки с этой информацией:
Если вы связываете общий объект, содержащий релоки доступа модели IE, для объекта будет установлен флаг DF_STATIC_TLS. По спецификации это означает, что dlopen может отказаться его загружать.
Глядя на /usr/include/elf.h
, мы имеем:
/* Values of `d_un.d_val' in the DT_FLAGS entry. */
...
#define DF_STATIC_TLS 0x00000010 /* Module uses the static TLS model */
Поэтому вам нужно проверить, установлен ли DF_STATIC_TLS
в записи DT_FLAGS
общей библиотеки.
Для проверки я создал простой фрагмент кода, используя локальное хранилище потока:
static __thread int foo;
void set_foo(int new) {
foo = new;
}
Затем я дважды скомпилировал его с двумя разными моделями локального хранилища потоков:
gcc -ftls-model=initial-exec -fPIC -c tls.c -o tls-initial-exec.o
gcc -shared tls-initial-exec.o -o tls-initial-exec.so
gcc -ftls-model=global-dynamic -fPIC -c tls.c -o tls-global-dynamic.o
gcc -shared tls-global-dynamic.o -o tls-global-dynamic.so
И, конечно же, я вижу разницу между двумя библиотеками, использующими readelf
:
$ readelf --dynamic tls-initial-exec.so
Dynamic section at offset 0xe00 contains 25 entries:
Tag Type Name/Value
...
0x000000000000001e (FLAGS) STATIC_TLS
В версии tls-global-dynamic.so
не было записи DT_FLAGS
, предположительно потому, что в ней не были установлены какие-либо флаги. Таким образом, должно быть довольно легко создать скрипт, используя readelf
и grep
для поиска затронутых библиотек.
person
James Henstridge
schedule
11.04.2014