Déplacement vers un système de construction Linux différent, obtention de l’erreur: symbole non défini: stat

Cela peut simplement être un problème avec le système de construction vers lequel je migre, mais je vais inclure les différences entre les deux systèmes et la façon dont j’ai rencontré le problème.

Mon ancien système de compilation est une machine SLES 10. La version de gcc / cpp / g ++ est 4.1.0

Mon nouveau système est sous SLES 11 SP4 et la version de gcc / cpp / g ++ est 4.3.4.

Je construis une bibliothèque partagée; la construction et la liaison fonctionnent bien sur le nouveau système. Cependant, au moment du chargement sur le nouveau système, je reçois ce qui suit:

error ./mysharedlib.so: undefined symbol: stat 

Puisque la fonction stat () est incluse dans /usr/include/sys/stat.h, j’ai examiné glibc sur les deux systèmes. Vieux:

 # rpm -q -f /usr/include/sys/stat.h glibc-devel-2.4-31.2 

et nouveau:

 # rpm -q -f /usr/include/sys/stat.h glibc-devel-2.11.3-17.95.2 

J’ai aussi regardé la sortie objdump liée à stat () sur l’ancien système:

 # objdump -T mysharedlib.so | grep stat 0000000000000000 D *UND* 0000000000000000 __xstat # objdump -x mysharedlib.so | grep stat 00000000000e3f8a l F .text 0000000000000024 stat 0000000000000000 *UND* 0000000000000000 __xstat 

Et le nouveau système:

 # objdump -T mysharedlib.so | grep stat 0000000000000000 D *UND* 0000000000000000 stat 0000000000000000 D *UND* 0000000000000000 lstat # objdump -x mysharedlib.so | grep stat 0000000000000000 *UND* 0000000000000000 stat 0000000000000000 *UND* 0000000000000000 lstat 

Cela me dit que sur l’ancien système, stat () était défini comme une fonction locale dans la section .text de mon object partagé réel. Stat n’est pas défini dans mysharedlib sur le nouveau système.

J’ai trouvé des informations sur feature_test_macros et j’ai pensé que cela pourrait résoudre le problème. J’ai donc ajouté features.h avant stat.h et mis à jour mon fichier makefile afin de définir _XOPEN_SOURCE:

 cc -D_XOPEN_SOURCE=500 

Cela n’a pas résolu le problème.

J’ai également essayé d’append “-lc” à mes drapeaux ld pour créer un lien dans libc. Cela semblait fonctionner, puisque c’est là que stat () est défini (je pense), mais ce n’est pas le cas.

À ce stade, j’ai trouvé cette question StackOverflow:

Pourquoi -O à gcc provoque-t-il la résolution de “stat”?

J’ai donc essayé d’append -O à mon fichier make en appelant g ++ sur le fichier qui appelle stat (). Cela semble résoudre le problème. Je ne sais probablement pas assez sur la résolution de symboles; Cependant, cela me semble un peu bidouillé. Suis-je loin de la base? Sinon, quelle est la bonne façon de résoudre l’erreur de temps de chargement sur le nouveau système?

Le problème que vous rencontrez est probablement dû à la construction de votre bibliothèque partagée avec ld . Le code de niveau utilisateur sur les systèmes UNIX ne doit jamais utiliser directement ld . Vous devez utiliser le pilote du compilateur ( g++ dans votre cas) pour effectuer le lien à la place.

Exemple:

 // tc #include  void fn(const char *p) { struct stat st; stat(p, &st); } gcc -fPIC -c tc ld -shared -o t.so to nm t.so | grep stat U stat ## problem: this library is not linked correctly 

Comparez à la bibliothèque correctement liée:

 gcc -shared -o t.so to nm t.so | grep stat 0000000000000700 t stat 0000000000000700 t __stat U __xstat@@GLIBC_2.2.5 

Pour trouver d’où vient le symbole de la stat locale ci-dessus, vous pouvez le faire:

 gcc -shared -o t.so to -Wl,-y,stat to: reference to stat /usr/lib/x86_64-linux-gnu/libc_nonshared.a(stat.oS): definition of stat 

Enfin, la raison pour laquelle U stat disparaît avec l’optimisation:

 gcc -E tc | grep -A2 ' stat ' extern int stat (const char *__ressortingct __file, struct stat *__ressortingct __buf) __atsortingbute__ ((__nothrow__ , __leaf__)) __atsortingbute__ ((__nonnull__ (1, 2))); gcc -E tc -O | grep -A2 ' stat ' __atsortingbute__ ((__nothrow__ , __leaf__)) stat (const char *__path, struct stat *__statbuf) { return __xstat (1, __path, __statbuf); 

C’est vrai: vous obtenez différentes sources prétraitées en fonction du niveau d’optimisation.