2011-01-11 14 views
8

Estoy tratando de obtener más información sobre el control de versiones de la biblioteca en Linux y cómo ponerlo todo en práctica. Aquí está el contexto:Linux, GNU GCC, ld, scripts de versión y el formato binario ELF - ¿Cómo funciona?

- Tengo dos versiones de una biblioteca dinámica que exponen el mismo conjunto de interfaces, digamos libsome1.so y libsome2.so.

- Una aplicación está vinculada contra libsome1.so.

- Esta aplicación usa libdl.so para cargar dinámicamente otro módulo, digamos libmagic.so.

- Ahora libmagic.so está relacionado con libsome2.so. Obviamente, sin utilizar scripts de enlazador para ocultar símbolos en libmagic.so, en el tiempo de ejecución, todas las llamadas a las interfaces en libsome2.so se resuelven en libsome1.so. Esto se puede confirmar verificando el valor devuelto por libVersion() contra el valor de la macro LIB_VERSION.

- Por lo tanto, intento junto a compilar y vincular libmagic.so con una secuencia de comandos del enlazador que oculta todos los símbolos excepto 3 que se definen en libmagic.so y son exportados por este. Esto funciona ... O al menos los valores libVersion() y LIB_VERSION coinciden (e informa la versión 2 no 1).

- Sin embargo, cuando algunas estructuras de datos se serializan en el disco, noté cierta corrupción. En el directorio de la aplicación si elimino libsome1.so y creo un enlace suave en su lugar para apuntar a libsome2.so, todo funciona como se espera y no ocurre la misma corrupción.

No puedo evitar pensar que esto puede deberse a algún conflicto en la resolución de los símbolos del enlazador en tiempo de ejecución. He intentado muchas cosas, como tratar de vincular libsome2.so para que todos los símbolos se alisen a [email protected]@VER_2 (que todavía estoy confundido porque el comando nm -CD libsome2.so todavía muestra símbolos como symbol y no [email protected]@VER_2) ... ¡Nada parece funcionar! ¡¡¡¡¡¡Ayuda!!!!!!

Editar: Debería haberlo mencionado antes, pero la aplicación en cuestión es Firefox, y libsome1.so es libsqlite3.so enviado con él. No tengo la opción de volver a compilarlos. Además, el uso de scripts de versión para ocultar símbolos parece ser la única solución en este momento. Entonces, ¿qué sucede realmente cuando los símbolos están ocultos? ¿Se vuelven 'locales' para el SO? ¿No tiene conocimiento alguno de su existencia? ¿Qué sucede cuando una función exportada se refiere a un símbolo oculto?

+0

¿Has probado en http://unix.stackexchange.com/? – joksnet

+2

@joksnet: Pensé que stackexchange era para usuarios y no para desarrolladores ... Esta pregunta está relacionada con el desarrollo en C++ Linux ... ¿O simplemente estoy engañado? :) Editar: ¡Estoy equivocado! Por alguna razón, pensé que stackexchange = serverfault !! ¡No sabía de unix.stackexchange.com! – themoondothshine

+0

¡Sí! Porque todavía está en beta, y no tiene su propio dominio. – joksnet

Respuesta

4

tratar de compilar tanto libsome1.so y libsome2.so añadir versiones de símbolos, cada uno con su propia versión (utilice la opción --version-script a ld). Luego, vincula la aplicación y libmagic.so usando las nuevas bibliotecas. Entonces, libsome1.so y libsome2.so deben estar completamente separados.

Aún pueden surgir problemas si hay referencias no versionadas a los símbolos. Tales referencias pueden ser satisfechas por definiciones versionadas (de modo que es posible agregar versiones de símbolos a una biblioteca sin romper la compatibilidad binaria). Si hay varios símbolos del mismo nombre, a veces puede ser difícil predecir cuál será utilizado.

En cuanto a las herramientas, nm -D no muestra ninguna información sobre el control de versiones de símbolos. Pruebe objdump -T o readelf -s en su lugar.

+0

Gracias por la información. ¡Aprendí algo nuevo! Probablemente debería haberlo mencionado antes, pero la aplicación en cuestión es Firefox y 'libsome1.so' es' libsqlite3.so' enviado con ella. Así que no hay forma de que tenga la opción de recompilarlos. Sin embargo, probé tu solución en una muestra minimalista que había creado para modelar la situación ... ¡Y funcionó! – themoondothshine

+0

+1 a tu respuesta por enseñarme algo nuevo! – themoondothshine

+0

Te estoy otorgando la recompensa. Creo que esto es merecido; tu respuesta es buena ¡Ten más representantes! –

Cuestiones relacionadas