2012-06-12 21 views
7

He compartido el objeto A.so que vincula estáticamente a libssl.a & otro objeto compartido B.so que también vincula estáticamente libssl.a.Biblioteca estática cargada dos veces

A.so & B.so tiene símbolos de libssl.a en el alcance GLOBAL. Lo comprobé por readelf -s A.so

Tengo un ejecutable a.out que carga A.so y B.so. Cuando a.out terminó, obtengo un error libre doble en uno de los símbolos de libssl.a en A.so.

Aunque libssl.a está vinculado estáticamente a cada objeto compartido, ya que están expuestos en todo el mundo, es posible que se comparta el mismo símbolo en lugar de elegir su copia local.

¿Cuál es la solución? ¿Cómo hacer que los símbolos sean locales aquí?

Por favor, ayuda

+0

Recomendaría usar un depurador para confirmar su teoría. – jdigital

+0

¿Podría elaborar? – KodeWarrior

+0

Solo una pequeña cosa, porque no tengo idea de cómo aplicarlo a su situación: 'dlopen' tiene una bandera RTLD_LOCAL que en algunas circunstancias ayudaría exactamente en esta situación. Entonces, si abriste esas librerías con 'dlopen', probablemente no deberían interferir. – liori

Respuesta

5

Esto es realmente esperado. Una instancia de libssl.a interpone (probablemente un subconjunto de) la otra, y los resultados no son bonitos. Puede usar un script de versión (--version-script a ld, con -Wl, para cc) para controlar lo que se exporta desde A.so y B.so. Si algo no se exporta, tampoco se puede interponer.

Como alternativa, puede compilar libssl.a con indicadores de visibilidad como -fvisibility=hidden. Estos indicadores solo afectan al enlazador dinámico y no a los enlaces estáticos. Probablemente necesites compilarlo tú mismo de todos modos porque los archivos .a enviados tienden a contener código dependiente de la posición, destinado a vincularse con ejecutables. Solo algunas plataformas, como 32-bit x86, le permiten salirse con la suya al vincular dichos códigos en objetos compartidos y solo a cambio de las reubicaciones de texto.

dlopen con RTLD_LOCAL según lo sugerido en un comentario también debería funcionar, pero parece una falta de seguridad utilizar dlopen para este propósito.

Otra opción es usar el mismo libssl.so compartido en ambas bibliotecas.

Cuestiones relacionadas