Déterminez quels symboles de votre exécutable créent la dépendance vis-à-vis de la version indésirable 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
Regardez dans la bibliothèque dont vous dépendez pour voir s'il existe des symboles dans des versions plus anciennes auxquels vous pouvez vous lier :
$ 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
Nous avons de la chance !
Demander la version à GLIBC_2.2.5
dans votre code :
#include <limits.h>
#include <stdlib.h>
__asm__(".symver realpath,[email protected]_2.2.5");
int main () {
realpath ("foo", "bar");
}
Notez que GLIBC_2.3 n'est plus nécessaire :
$ 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
Pour plus d'informations, voir http://web.archive.org/web/20160107032111/http://www.trevorpounds.com/blog/?p=103.
Malheureusement, la solution de @ Sam ne fonctionne pas bien dans ma situation. Mais selon sa méthode, j'ai trouvé ma propre façon de résoudre ce problème.
Voici ma situation :
J'écris un programme C++ en utilisant le framework Thrift (c'est un middleware RPC). Je préfère le lien statique au lien dynamique, donc mon programme est lié à libthrift.a statiquement au lieu de libthrift.so . Cependant, libthrift.a est lié dynamiquement à glibc, et depuis mon libthrift.a est construit sur mon système avec glibc 2.15, mon libthrift.a utilise memcpy de la version 2.14([email protected]_2.14 ) fourni par glibc 2.15.
Mais le problème est que nos machines serveurs n'ont que la glibc version 2.5 qui n'a que [email protected]_2.2.5 . Il est bien inférieur à [email protected]_2.14 . Donc, bien sûr, mon programme serveur ne peut pas s'exécuter sur ces machines.
Et j'ai trouvé cette solution :
-
Utilisation de .symver pour obtenir la référence à [email protected]_2.2.5 .
-
Écrire mon propre __wrap_memcpy fonction qui appelle simplement [email protected]_2.2.5 directement.
-
Lors de la liaison de mon programme, ajoutez -Wl,--wrap=memcpy option à gcc/g++.
Le code impliqué dans les étapes 1 et 2 est ici :https://gist.github.com/nicky-zs/7541169