У меня есть общий объект Solaris (файл common.so), который запускается как часть стороннего приложения (app.exe). У меня нет доступа к исходному коду приложения. Для этого мне нужно добавить возможность публиковать http-запросы. Мой план — использовать libcurl с openssl. Сложность в том, что app.exe уже зависит от более старой версии curl (7.14), которая не поддерживает ssl с tls v1.2.
Я скачал исходный код и собрал файлы curl (7.55.1) и openssl .a. Я также смог собрать common.so со статической зависимостью от этих архивных файлов. ldd не показывает зависимость от curl или ssl .so файлов и не сообщает об ошибках «Symbol not found».
С этим результатом я ожидал, что моя версия curl будет вызвана, когда она запускается как часть приложения, но не запускается. Вместо этого curl_version () отображает более старую версию, и я получаю сообщение об ошибке unknown ssl protocol error
Я использую компилятор студии Solaris. Приложение не зависит напрямую от библиотек curl, но зависит от другого файла .so, который экспортирует символы с такими же именами, как и в curl. Я понял из nm, и я предполагаю, что этот .so файл также статически скручивается.
Когда app.exe загружает два рассматриваемых SO, он добавляет функции каждого в свою таблицу символов. Теперь один из двух возможных сценариев должен происходит (что на самом деле является деталью ОС, но здесь не имеет значения …):
Теперь самое чистое решение — если применимо, т.е. е. если у вас есть доступ к источникам — обновите другой SO, чтобы использовать более новую версию curl. В этом случае рассмотрите возможность создания curl в качестве нового SO, а не статически связывать его как с common.so, так и с другим SO.
В противном случае, чтобы решить проблему напрямую, вам придется изменить порядок загрузки приложением SO, что, вероятно, будет означать декомпиляцию app.exe и ее перестройку с измененным порядком связывания SO. Проблема тогда: тогда может быть две версии app.exe, и вы должны убедиться, что только одна правильная распространяется с вашим common.so. Потенциальный источник неприятностей тоже …
Помимо этого, лучшее, что я могу придумать, это обходной путь:
Вы можете изменить префикс curl из curl_
палец. г. curl_755_
, Не пытайтесь сделать это вручную, однако, вы, скорее всего, сойдете с ума таким образом … Вместо этого используйте скрипт (например, perl или python). И если вы когда-нибудь обновите источники curl, вы можете просто запустить его снова …
Более быстрая версия, но потенциально небезопасная: просто замените любые случаи. Безопаснее: определите внешне видимые функции (и, возможно, глобальные объекты) при первом запуске и сохраните их на карте, а затем замените любое вхождение строки, содержащейся в карте, на соответствующее значение.
Последний подход (карта) дополнительно позволяет генерировать макросы в заголовочных файлах следующего вида:
#define curl_xyz curl_755_xyz
Эти макросы позволяют источникам common.so выглядеть так, как если бы использовались оригинальные источники curl …
Других решений пока нет …