Обнаружение двух ABI-несовместимых версий моей общей библиотеки, загруженных в одну программу
Я написал общую библиотеку с несколькими несовместимыми версиями. Я изменил SONAME, поэтому они называются:
- lib_mylib.so.1.0.0 (старая библиотека)
- lib_mylib.so.2.0.0
Некоторые функции есть только в mylib.so.1, другие - только в mylib.so.2, и многие функции являются общими (но некоторые изменили количество аргументов).
И я боюсь, что можно связать обе версии mylib в одно приложение, например, когда само приложение большое и состоит из множества библиотек. Когда приложение перестраивается частично, может возникнуть такая ситуация:
- заявка
- app_lib1.so (был построен с mylib.so.1 - первая версия моей библиотеки)
- app_lib2.so (был перестроен с mylib.so.2 - вторая версия)
Я уже видел приложение с загруженными в него обеими версиями (ldd
сообщает оба).
Итак, возможно ли добавить некоторый проверочный код в mylib.so.2, чтобы обнаружить, что обе версии библиотеки уже загружены и имеют конфликтующий интерфейс ABI/Interface. (Я не могу изменить lib_mylib.so.1, чтобы добавить что-то в него)
2 ответа
Вы можете изменить свою библиотеку версии 2 для разрешения некоторого символа версии 1 (dlsym(3)
) во время инициализации и сбоя при обнаружении.
Пример:
extern __attribute__((constructor)) void _version_check2()
{
if (dlsym(RTLD_DEFAULT, "version_1_function"))
abort();
}
Более изящное решение - позволить библиотеке версии 2 имитировать поведение версии 1, но это вводит устаревший код.
РЕДАКТИРОВАТЬ
Чтобы быть в будущем, вы также можете ввести статическую переменную версии, и все вызовы функций будут проверять, соответствует ли она текущей. Затем в будущих версиях вам просто нужно изменить значение этой переменной и аварийно завершить работу при несовпадении.
РЕДАКТИРОВАТЬ 2
Вы также можете вызывать эту функцию для каждой функции версии 2, чтобы рано или поздно, когда загружается версия 1, ваше приложение зависало.
Вы можете разобрать /proc/self/maps
получить список загруженных в данный момент объектов.