Справочная информация: У меня есть приложение, часть которого используется как библиотека для другого независимого приложения. Они ссылаются на эту библиотеку (скажем, lib.so) на время связывания. Проблема с таким подходом заключается в том, что мы должны использовать такие же внешние библиотеки, как boost, ace и т. Д., Или у нас будут дублированные символы, которые в итоге вызовут сбой. Мы хотим решить эту проблему.Динамическая загрузка разделяемой библиотеки с помощью RTLD_DEEPBIND
Я знаю два метода - один скрывает все символы (не уверен в порядках областей видимости глобальных/локальных для общей библиотеки), а другой - для динамической компоновки. Мы выбрали 2-й вариант (динамическое связывание), так как это дало возможность клиенту провести легкое тестирование с помощью stubbed lib.so. и у нас очень простое api.
Я написал ниже небольшой пример приложения, которое загружает пример разделяемой библиотеки и сбой (я хочу понять, почему он разбился и как он должен быть написан). Crash находится в dlopen, точно в инициализации глобальной переменной при присваивании std :: string (конструктор типа Aclass). Из нашего тестирования видно, что любой доступ к библиотеке std при текущей инициализации библиотеки приведет к сбою.
Нам удалось удалить сбой, добавив флаг -fPIC в EXECUTABLE (почему это разрешило нашу проблему, я думал, что он должен быть установлен для общей библиотеки, может ли кто-нибудь объяснить мне это более точно)? Ненужное для моего понимания этот флаг проблематичен, поскольку он замедляет приложение, и в моем случае (приложения с низкой задержкой) это довольно проблематично.
К резюме: 1. Почему произошел сбой? 2. Почему флага -fPIC достаточно, чтобы решить эту проблему? 3. Почему достаточно установить флаг -fPIC в исполняемый файл? 4. Возможно ли разрешить мою проблему другим способом, чтобы разделяемая библиотека и клиентское приложение могли использовать разные версии библиотек (например, boost, ace и т. Д., Компилятор, Linux-версия и библиотеки std, чтобы быть одинаковыми)? 5. Удаление флага RTLD_DEEPBIND также исправляет ошибку, но из gcc man он выглядит так, что я должен использовать этот флаг, поскольку он изменит порядок видимости символа для общей библиотеки - сначала он будет искать символы в локальной области, а затем в глобальном - выглядит так, как это должно быть для я как разделяемая библиотека будет использовать разные внешние библиотеки, чем исполняемый файл (а динамическая загрузка защитит исполняемый файл, загрязняя его область символов). Зачем удалять эту ошибку с исправлением флага в этом простом случае?
Shared библиотека dynLib.cpp:
#include <string>
class Aclass
{
std::string s;
s = "123";
}
Aclass a;
Exacutable main.cpp:
#include <stdlib.h>
#include <dlfcn.h>
#include <string>
#include <unistd.h>
#include <iostream>
int main()
{
std::string dummyCrasher;
dlerror();
void* handle = dlopen("./libdynLib.so", RTLD_LAZY | RTLD_LOCAL | RTLD_DEEPBIND);
if(!handle)
{
std::cout << "handle is null" << dlerror();
}
usleep(1000 * 1000 * 10);
}
Makefile: Makefile
CXXFLAGS=-m32 -march=x86-64 -Wl,v -g -O3 -Wformat -Werror=format -c
CLINKFLAGS=-Wl,-Bstatic -Wl,Bdynamic -ldl -m32 -march=x86-64
all: dynLib.so dynamiclinking
dynLib.so: dynLib.o
g++44 $(CLINKFLAGS) -shared -o libdynLib.so dynLib.o
dynLib.o: dynLib.cpp
g++44 $(CXXFLAGS) dynLib.cpp
dynamiclinking: main.o
g++44 $(CLINKFLAGS) -o dynamiclinking main.o -ldl
main.o: main.cpp
g++44 (CXXFLAGS) main.cpp
.PHONY: clean
clean:
rm dynLib.o main.o dynamiclinking libdynLib.so
PS. Я пишу этот код вручную (может сделал некоторые ошибки правописания) PS 2. с -fPIC флагом он будет работать:
main.o: main.cpp
g++44 (CXXFLAGS) main.cpp -fPIC
UPDATE можно решить эту проблему путем статического связывания libstdC++. Но все еще мои вопросы не отвечают :(Может быть, у кого-то есть время, чтобы посмотреть на это?
UPDATE2 Такая же проблема возникает в GCC 4.4.6 и 4.8.1.
У меня недавно возникла аналогичная проблема и нашла этот отчет об ошибке: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=42679 Это не дает полного решения, но, надеюсь, некоторое понимание проблемы на наименее. – Filip