Загрузка нескольких общих библиотек с разными версиями - PullRequest
16 голосов
/ 23 октября 2008

У меня есть исполняемый файл в Linux, который загружает libfoo.so.1 (это SONAME) как одну из его зависимостей (через другую общую библиотеку). Он также ссылается на другую системную библиотеку, которая, в свою очередь, ссылается на версию system , libfoo.so.2. В результате и libfoo.so.1 и libfoo.so.2 загружаются во время выполнения, и код, который должен был вызывать функции из библиотеки с версией 1, в итоге вызывает (двоично-несовместимые) функции из более новой системной библиотеки с версией 2, потому что некоторые символы остаются прежними. Результатом обычно является разрушение стека и последующий segfault.

Теперь библиотека, которая ссылается на более старую версию, является сторонней библиотекой с закрытым исходным кодом, и я не могу контролировать, с какой версией libfoo она компилируется. Предполагая, что единственная оставшаяся опция - это перестройка группы системных библиотек, которые в настоящее время связаны с libfoo.so.2 для связи с libfoo.so.1.

Есть ли способ избежать замены системных библиотек локальными копиями, которые ссылаются на более старые libfoo? Могу ли я загрузить обе библиотеки и получить код, вызывающий правильную версию символов? Так что мне нужно специальное управление версиями на уровне символов?

Ответы [ 2 ]

7 голосов
/ 24 октября 2008

Возможно, вы сможете выполнить некоторые трюки с версией скрипта:

http://sunsite.ualberta.ca/Documentation/Gnu/binutils-2.9.1/html_node/ld_26.html

Это может потребовать, чтобы вы написали обертку вокруг вашей библиотеки lib, которая извлекает libfoo.so.1, которая явно экспортирует некоторые символы и маскирует все остальные как локальные. Например:

MYSYMS { Глобальный: foo1; foo2; местный: *; };

и используйте это, когда вы связываете эту оболочку как:

gcc -shared -Wl, - скрипт-версии, mysyms.map -o mylib wrapper.o -lfoo -L / path / to / foo.so.1

Это должно сделать символы libfoo.so.1 локальными для оболочки и недоступными для основного exe.

0 голосов
/ 23 октября 2008

Я могу только придумать обходной путь. Что было бы статически связать версию "системной библиотеки", которую вы используете. Для вашей статической сборки вы можете сделать так, чтобы она ссылалась на ту же старую версию, что и сторонняя библиотека. Учитывая, что он не полагается на более новую версию ...

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

...