2008-10-23 22 views
15

Tengo un archivo ejecutable en Linux que carga libfoo.so.1 (es decir, SONAME) como una de sus dependencias (a través de otra biblioteca compartida). También se vincula a otra biblioteca del sistema, que, a su vez, enlaza a una versión del sistema , libfoo.so.2. Como resultado, libfoo.so.1 y libfoo.so.2 se cargan durante la ejecución, y el código que se suponía llamaría funciones de la biblioteca con la versión 1 termina llamando funciones (binarias incompatibles) de una biblioteca del sistema más nueva con la versión 2, porque algunos símbolos permanecen lo mismo. El resultado es generalmente un aplastamiento de pila y una segfault posterior.Cargando múltiples bibliotecas compartidas con diferentes versiones

Ahora, la biblioteca que enlaza con la versión anterior es una biblioteca de código fuente de terceros, y no puedo controlar la versión de libfoo contra la que compila. Asumiendo eso, la única opción restante es reconstruir un grupo de bibliotecas del sistema que actualmente enlazan con libfoo.so.2 para vincular con libfoo.so.1.

¿Hay alguna manera de evitar reemplazar las bibliotecas del sistema con copias locales que enlazan con las anteriores libfoo? ¿Puedo cargar ambas bibliotecas y tener el código llamando a la versión correcta de los símbolos? ¿Entonces necesito un control de versiones especial a nivel de símbolo?

+0

Alex: ¿cómo resolvió el problema? ¿podrías compartirlo con nosotros? – Nawaz

+0

@Nawaz No recuerdo exactamente, ¡ha sido hace 9 años! Creo que me rendí y lo hice para que solo se cargue una versión de la biblioteca. –

+0

Alex, [este artículo] (https://blog.habets.se/2012/05/Shared-libraries-diamond-problem.html) habla sobre este problema y también ha sugerido una solución. No lo he intentado todavía Pero es interesante saber/explorar. – Nawaz

Respuesta

0

Solo puedo pensar en una solución alternativa. Lo cual sería vincular estáticamente una versión de la "biblioteca del sistema" que está utilizando. Para su compilación estática, puede hacer que enlace contra la misma versión anterior que la biblioteca de terceros. Dado que no se basa en la versión más reciente ...

Quizás también es posible evitar estos problemas al no vincular la biblioteca de terceros de la forma habitual. En cambio, su programa podría cargarlo en el momento de la ejecución. Quizás entonces podría oscurecerse contra el resto. Pero no sé mucho sobre eso.

7

Usted puede ser capaz de hacer algunos trucos de guión versión:

http://sunsite.ualberta.ca/Documentation/Gnu/binutils-2.9.1/html_node/ld_26.html

Esto puede requerir que escriba una envoltura alrededor de su lib que tira en libfoo.so.1 que exporta algunos símbolos de manera explícita y máscaras todos los demás como locales. Por ejemplo:

MYSYMS { global: foo1; foo2; local: *; };

y utilizar esto cuando se vincula tal envoltorio como:

gcc -compartida -Wl, - versión de la escritura, mysyms.map -o mibiblioteca wrapper.o -lfoo -L/ruta/a/foo. so.1

Esto debería hacer que los símbolos de libfoo.so.1 sean locales al wrapper y no estén disponibles para el exe principal.

Cuestiones relacionadas