Наш проект (С++, Linux, gcc, PowerPC) состоит из нескольких разделяемых библиотек. При выпуске новой версии пакета должны быть изменены только те библиотеки, исходный код которых действительно был затронут. С "изменением" я подразумеваю абсолютную двоичную идентификацию (сравнивается контрольная сумма по файлу. Различная контрольная сумма → другая версия в соответствии с политикой). (Я должен упомянуть, что весь проект всегда строится сразу, независимо от того, изменился ли какой-либо код или нет в библиотеке).
Обычно это может быть достигнуто путем скрытия частных частей включенных файлов заголовков и не изменения общедоступных.
Однако был случай, когда в деструктор класса TableManager (в файле TableManager.cpp!) библиотеки libTableManager.so был добавлен простой delete
, но все же двоичная/контрольная сумма библиотеки libB.so(который использует класс TableManager).
TableManager.h:
class TableManager
{
public:
TableManager();
~TableManager();
private:
int* myPtr;
}
TableManager.cpp:
TableManager::~TableManager()
{
doSomeCleanup();
delete myPtr; // this delete has been added
}
Проверяя libB.so на readelf --all libB.so
, глядя на раздел .dynsym, выяснилось, что длина всех функций, даже динамически используемых из других библиотек, хранится в libB! Это выглядит так (длина - 668 в третьем столбце):
527: 00000000 668 FUNC GLOBAL DEFAULT UND _ZN12TableManagerD1Ev
Итак, мои вопросы:
- Почему длина функции фактически хранится в клиентской библиотеке? Достаточно ли начального адреса?
- Может ли это быть подавлено каким-то образом при компиляции/связывании libB.so(вид "зачистки" )? Мы действительно хотели бы уменьшить эту степень зависимости...