Averigüe qué símbolos en su ejecutable están creando la dependencia de la versión no deseada de glibc.
$ objdump -p myprog
...
Version References:
required from libc.so.6:
0x09691972 0x00 05 GLIBC_2.3
0x09691a75 0x00 03 GLIBC_2.2.5
$ objdump -T myprog | fgrep GLIBC_2.3
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.3 realpath
Mire dentro de la biblioteca de la que depende para ver si hay algún símbolo en versiones anteriores con el que pueda vincular:
$ objdump -T /lib/libc.so.6 | grep -w realpath
0000000000105d90 g DF .text 0000000000000021 (GLIBC_2.2.5) realpath
000000000003e7b0 g DF .text 00000000000004bf GLIBC_2.3 realpath
¡Estamos de suerte!
Solicite la versión de GLIBC_2.2.5
en tu código:
#include <limits.h>
#include <stdlib.h>
__asm__(".symver realpath,[email protected]_2.2.5");
int main () {
realpath ("foo", "bar");
}
Observe que GLIBC_2.3 ya no es necesario:
$ objdump -p myprog
...
Version References:
required from libc.so.6:
0x09691a75 0x00 02 GLIBC_2.2.5
$ objdump -T myprog | grep realpath
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 realpath
Para obtener más información, consulte http://web.archive.org/web/20160107032111/http://www.trevorpounds.com/blog/?p=103.
Desafortunadamente, la solución de @Sam no funciona bien en mi situación. Pero de acuerdo con su manera, encontré mi propia manera de resolver eso.
Esta es mi situación:
Estoy escribiendo un programa C++ usando el marco Thrift (es un middleware RPC). Prefiero el enlace estático al enlace dinámico, por lo que mi programa está vinculado a libthrift.a estáticamente en lugar de libthrift.so . Sin embargo, libthrift.a está vinculada dinámicamente a glibc, y desde mi libthrift.a está construido en mi sistema con glibc 2.15, mi libthrift.a usa memcpy de la versión 2.14([email protected]_2.14 ) proporcionado por glibc 2.15.
Pero el problema es que nuestras máquinas servidor solo tienen la versión 2.5 de glibc que solo tiene [email protected]_2.2.5 . Es mucho más bajo que [email protected]_2.14 . Entonces, por supuesto, mi programa de servidor no puede ejecutarse en esas máquinas.
Y encontré esta solución:
-
Usando .symver para obtener la referencia a [email protected]_2.2.5 .
-
Escribir mi propio __wrap_memcpy función que simplemente llama a [email protected]_2.2.5 directamente.
-
Al vincular mi programa, agregue -Wl,--wrap=memcpy opción a gcc/g++.
El código involucrado en los pasos 1 y 2 está aquí:https://gist.github.com/nicky-zs/7541169