2012-06-12 3 views
7

У меня есть общий объект A.so, который статически ссылается на libssl.a & другой общий объект B.so, который также статически связывает libssl.a.Статическая библиотека загружена дважды

A.so & B.so имеет символы из libssl.a в GLOBAL scope. Я проверил это readelf -s A.so

У меня есть исполняемый файл a.out, который загружает A.so и B.so. Когда a.out завершено, я получаю двойную бесплатную ошибку в одном из символов libssl.a в A.so.

Несмотря на то, что libssl.a статически привязан к каждому общему объекту, поскольку они открыты глобально возможно, что один и тот же символ является общим, а не собирает его локальную копию.

Что такое обходной путь? Как сделать здесь символы здесь?

Помогите

+0

Я бы рекомендовал использовать отладчик, чтобы подтвердить вашу теорию. – jdigital

+0

Не могли бы вы разработать? – KodeWarrior

+0

Небольшая вещь, потому что я понятия не имею, как применить ее к вашей ситуации: 'dlopen' имеет флаг RTLD_LOCAL, который в некоторых случаях поможет именно в этой ситуации. Поэтому, если вы открыли эти библиотеки с помощью 'dlopen', они, вероятно, не должны мешать. – liori

ответ

5

Это действительно ожидается. Один экземпляр libssl.a вмещает (вероятно, подмножество) другого, и результаты не очень хороши. Вы можете использовать сценарий версии (--version-script - ld, с -Wl, для cc), чтобы контролировать то, что экспортируется с A.so и B.so. Если что-то не экспортируется, оно также не может быть вставлено.

В качестве альтернативы вы можете скомпилировать libssl.a с флагами видимости, такими как -fvisibility=hidden. Эти флаги влияют только на динамический компоновщик, а не на статическую связь. Скорее всего, вам нужно было скомпилировать его самостоятельно, потому что отправленные файлы .a обычно содержат код, зависящий от позиции, предназначенный для соединения с исполняемыми файлами. Только некоторые платформы, такие как 32-разрядная x86, позволяют вам уйти с привязкой такого кода к общим объектам и только за счет перераспределения текста.

dlopen с RTLD_LOCAL, как предложено в комментарии, также должно работать, но для этой цели кажется, что для этого используется hackish для использования dlopen.

Другой вариант заключается в использовании того же общего libssl.so в обеих библиотеках.