У меня есть приложение C++ с кросс-платформой, которое разбито на несколько разделяемых библиотек и загружает дополнительные функции из разделяемых библиотек плагинов. Библиотеки плагинов должны быть автономными и работать сами по себе, без знания или зависимости от вызывающего приложения.Segfault на библиотеке плагинов C++ с повторяющимися символами
Один из плагинов содержит скопированный код из основного приложения, поэтому содержит имена символов, дублирующиеся с именами в движке. (Да, я знаю, что это вообще не-нет, но в то время, когда был написан плагин, движок был монолитным двоичным и не мог делиться библиотеками.) В Windows все работает нормально. В Linux мы получали segfaults. Посмотрев на трассировку стека ошибки, она возникала в плагине при вызове функций в двойном имени класса. Это, по-видимому, было результатом того, что движок и плагин имели несколько разные версии общего кода (некоторые функции класса были закомментированы в плагине). Это было похоже на то, что плагин получал свои символы, связанные с движком, вместо собственного. Мы «исправили» проблему, изменив параметры dlopen
на dlopen(pFilepath, RTLD_LAZY | RTLD_LOCAL)
.
Но когда мы переписывали движок, который должен быть разделен на разделяемые библиотеки (для возможной цели повторного использования в плагинах), мы снова получаем ошибку segfault. И, глядя на трассировку стека, он идет от движка -> плагин -> движок.
Есть ли способ указать для компоновщика времени выполнения не отображать символы плагина в движке (особенно если они определены в плагине)?
Спасибо! Matt
Edited 2009-12-3
Я первый попытался обернуть код плагина в его собственном пространстве имен. Это не сработало, потому что оно статически связано с библиотекой, которая также связана с движком. Варианты статической библиотеки разные, поэтому segfault!
Затем я изменил сборку двигателя, и его библиотеки стали статически связаны. И когда я запускаю его, у меня больше нет проблемы. Таким образом, похоже, что это было результатом экспорта экспортированных общих библиотек, а затем динамического перемещения в плагин при его открытии. Но когда весь код двигателя находится в одном исполняемом файле, он не экспортирует свои символы (поэтому он не пытается переместить символы плагина в движок).
У меня все еще проблема, так как есть параллельная версия программы (с использованием Open-MPI) и которая все еще получает segfault. Он появляется в том, что он все еще экспортирует символы двигателя и перемещает плагин. Это может быть связано с тем, как Open-MPI выполняет приложение.
Есть ли какие-либо флагов компоновщика, которые могут быть использованы в общей библиотеке плагинов, которые говорят, что это не приведет к динамическому перемещению символов во время выполнения? Или скрыть свои символы, чтобы они не переселились? Я пробовал -s
(«Опустить всю информацию о символах»), но это, по-видимому, не изменило динамические символы (проверено с использованием nm -D <plugin>
).
Являются ли эти символы глобальными или именами функций? Можете ли вы внести незначительные изменения в код? –
Это классы и их функции-члены. Есть 36 файлов, используемых из кодовой базы двигателя, поэтому я не хочу изменять каждое имя или файл класса. Хотя конечной целью является переписать плагин из-за ограничений по времени и проверки кода, который я не хочу, если мне это не нужно. – CuppM
@CuppM, так, например, у вас есть класс «Foo» с членом «bar», определенным в 2-х местах? И «Foo» находится в том же пространстве имен в обоих случаях? Если это так, это никогда не будет работать правильно для вас. Переместите одно из «Foo» в собственное пространство имен, и жизнь будет проще. – Glen