2

У меня есть две разделяемые библиотеки, конфликтующие друг с другом, и другие связанные с ними двоичные файлы. Чтобы быть более подробными, у меня есть что-то вроде этого:Двоичные файлы связаны с разными разделяемыми библиотеками того же пакета

  • top-lib1.so связанного с libprotobuf.so;
  • top-lib2.so связанный с libprotobuf-lite.so;
  • двоичная связаны с top-lib1.so и top-lib2.so.

Проблема заключается в том, что когда я запускаю мой двоичной, я сбой из-за какое-то повреждение памяти, вызванным двойными бесплатно: первый из protobuf.so и второй из protobuf-lite.so (см. related bug).

я не доступ к top-lib2.so источников, и я не могу связать top-lib1.so с protobuf-lite.so из-за моей функциональности приложения.

Таким образом, мой вопрос: как с этим бороться?

Я не могу оставить как из-за этого аварии, я не могу повторно связать свою LIB (top-lib1.so) с libprotobuf-lite.so, и я не могу изменить сверху -lib2.so.

Есть ли способ восстановить связь top-lib2.so с libprotobuf.so без источников? Или есть ли другая возможность?

+0

Обычно общие библиотеки, которые зависят от других разделяемых библиотек, вообще не связывают своих иждивенцев. Это означает, что вам нужно будет связать ваш исполняемый файл с 'libprotobuf.so', и все должно работать. Можете ли вы запустить 'ldd top-lib1.so' и' ldd top-lib2.so' и показать нам, действительно ли они связаны с библиотекой protobuf? И покажите нам свою командную строку связи для окончательного исполняемого файла. –

+0

@John Zwinck: 'ldd top-lib2.so | grep proto': * libprotobuf-lite.so.9 => /usr/lib/x86_64-linux-gnu/libprotobuf-lite.so.9 (0x00007fa17d190000) *; 'ldd top-lib1.so | grep proto': * libprotobuf.so.9 => /usr/lib/x86_64-linux-gnu/libprotobuf.so.9 (0x00007f9431d94000) *; ** окончательный исполняемый файл **: 'g ++ -o test test.cpp -ltop-lib2.so -ltop-lib1.so'; 'ldd test | grep proto': * libprotobuf.so.9 => /usr/lib/x86_64-linux-gnu/libprotobuf.so.9 (0x00007fe639b24000); libprotobuf-lite.so.9 => /usr/lib/x86_64-linux-gnu/libprotobuf-lite.so.9 (0x00007fe625b0a000) * – avtomaton

+0

Каковы ваши командные строки компоновщика? Для 'top-lib1.so' и исполняемого файла. –

ответ

3

У вас есть несколько вариантов.

В приведенной выше ошибке вы указываете, что «libprotobuf.so имеет все, что есть libprotobuf-lite.so имеет и более». Если это действительно так, одно из возможных решений состоит в раздел .dynamic для ссылки libprotobuf.so вместо -lite.so. Первый короче, поэтому просто переписывать строку libprotobuf-lite.so с libprotobuf.so\0e.so - это все, что вам нужно.

Если вы не хотите, чтобы бинарная повязка top-lib2.so, у вас есть другие варианты:

  1. Вы можете компоновать все top-lib1.so, содержащие объектные файлы и все из них libprotobuf.so в основной двоичный файл и скрыть все символы libprotobuf (через скрипт компоновщика). Если вы это сделаете, top-lib2.soне может сообщить, что есть что угодно, кроме libprotobuf-lite.so, которого он ожидает.

  2. Вы могли бы сделать то же самое с top-lib1.so - т.е. скрытьlibprotobuf внутри него.

  3. Вы можете связать свою копию libprotobuf.so с -Wl,--default-symver, который добавит @@libprotobuf.so версии к каждому символу, экспортируемой из libprotobuf.so, и избежать столкновения символа, который вызывает проблемы в первую очередь.

+0

Проблема не в столкновении символов. Проблема состоит в том, что в результате двоичный ** вызывает ** некоторую функцию срыва ** дважды **, а ** libprotobuf ** просто не может справиться с этой ситуацией. Я даже не уверен, что ссылка на одну и ту же библиотеку поможет исправить эту проблему. Но спасибо, ты ответил на мой вопрос. – avtomaton

+0

@avtomaton Я не верю, что вы понимаете проблему. Вызов функции разрыва дважды на * отдельные * объекты в порядке. Вызывать его на * том же * объекте нет. Две библиотеки пытаются скрыть * тот же * объект * точно * из-за столкновения символа (глобальной переменной). –

Смежные вопросы