Estou tentando aprender mais sobre o controle de versão da biblioteca no Linux e como colocar tudo para funcionar. Aqui está o contexto:
- Eu tenho duas versões de uma biblioteca dinâmica que expõem o mesmo conjunto de interfaces, digamos libsome1.so
e libsome2.so
.
- Um aplicativo está vinculado libsome1.so
.
- Este aplicativo usa libdl.so
para carregar dinamicamente outro módulo, digamos libmagic.so
.
- Agora libmagic.so
está ligado contra libsome2.so
. Obviamente, sem o uso de scripts de vinculador para ocultar símbolos libmagic.so
, em tempo de execução, todas as chamadas para interfaces libsome2.so
são resolvidas libsome1.so
. Isso pode ser confirmado verificando o valor retornado por libVersion()
contra o valor da macro LIB_VERSION
.
- Então, tento a seguir compilar e vincular libmagic.so
um script vinculador que oculte todos os símbolos, exceto os 3 definidos libmagic.so
e exportados por ele. Isso funciona ... Ou pelo menos libVersion()
e os LIB_VERSION
valores correspondem (e relata a versão 2 e não 1).
- No entanto, quando algumas estruturas de dados são serializadas em disco, notei alguma corrupção. No diretório do aplicativo, se eu excluir libsome1.so
e criar um link virtual em seu lugar para apontar libsome2.so
, tudo funcionará conforme o esperado e a mesma corrupção não ocorrerá.
Não posso deixar de pensar que isso pode ser causado devido a algum conflito na resolução de símbolos do vinculador em tempo de execução. Eu tentei muitas coisas, como tentar vincular libsome2.so
para que todos os símbolos sejam aliados symbol@@VER_2
(sobre o qual ainda estou confuso porque o comando nm -CD libsome2.so
ainda lista os símbolos como symbol
e não symbol@@VER_2
) ... Nada parece funcionar !!! Socorro!!!!!!
fonte
RTLD_LOCAL
eRTLD_DEEPBIND
dlopen no seu aplicativo. Não tenho tempo para testar isso agora, mas deve funcionar com base na página de manual.Respostas:
Isso não responde exatamente à sua pergunta, mas ...
Antes de tudo, ELF é a especificação usada pelo Linux para arquivos executáveis (programas), bibliotecas compartilhadas e também arquivos de objetos, que são os arquivos intermediários encontrados na compilação de software. Os arquivos de objeto terminam em .o, as bibliotecas compartilhadas terminam com .so, seguidos por zero ou mais dígitos separados por pontos, e os arquivos executáveis não têm extensão normalmente.
Normalmente, existem três formulários para nomear uma biblioteca compartilhada; o primeiro formulário simplesmente termina em .so. Por exemplo, uma biblioteca chamada readline é armazenada em um arquivo chamado libreadline.so e está localizada em um de / lib, / usr / lib ou / usr / local / lib normalmente. Esse arquivo está localizado ao compilar o software com uma opção como -lreadline. -l informa ao compilador para vincular à seguinte biblioteca. Como as bibliotecas mudam de tempos em tempos, elas podem se tornar obsoletas, de modo que as bibliotecas incorporam algo chamado SONAME. O SONAME para readline pode parecer com libreadline.so.2 para a segunda versão, versão principal do libreadline. Também pode haver muitas versões secundárias do readline que são compatíveis e não exigem a recompilação do software. Uma versão secundária do readline pode ser denominada libreadline.so.2.14. Normalmente libreadline. assim, é apenas um link simbólico para a versão principal mais recente do readline, libreadline.so.2, neste caso. libreadline.so.2 também é um link simbólico para libreadline.so.2.14, que na verdade é o arquivo que está sendo usado.
O SONAME de uma biblioteca é incorporado dentro do próprio arquivo da biblioteca. Em algum lugar dentro do arquivo libreadline.so.2.14 está a string libreadline.so.2. Quando um programa é compilado e vinculado ao readline, ele procura o arquivo libreadline.so e lê o SONAME incorporado. Posteriormente, quando o programa for realmente executado, ele carregará libreadline.so.2, não apenas libreadline.so, já que esse foi o SONAME que foi lido quando foi vinculado pela primeira vez. Isso permite que um sistema tenha várias versões incompatíveis do readline instaladas e cada programa carregará a versão principal apropriada à qual foi vinculado. Além disso, ao atualizar o readline, digamos, para 2.17, eu posso instalar o libreadline.so.2.17 ao lado da biblioteca existente e, uma vez que movo o link simbólico libreadline.so.2 de libreadline.so.2.13 para libreadline.so.2.17,
fonte