dlsym renvoie NULL, même si le symbole existe

J’utilise dlsym pour rechercher des symboles dans mon programme, mais il renvoie toujours NULL, ce à quoi je ne m’attends pas. Selon la page de manuel, dlsym peut renvoyer NULL s’il y a eu une erreur ou si le symbole est NULL. Dans mon cas, je reçois une erreur. Je vais vous montrer le MCVE que j’ai fait ce soir.

Voici le contenu de instr.c:

#include  void * testing(int i) { printf("You called testing(%d)\n", i); return 0; } 

Une chose très simple ne contenant qu’un exemple de fonction non remarquable.

Voici le contenu de test.c:

 #include  #include  #include  typedef void * (*dltest)(int); int main(int argc, char ** argv) { /* Declare and set a pointer to a function in the executable */ void * handle = dlopen(NULL, RTLD_NOW | RTLD_GLOBAL); dlerror(); dltest fn = dlsym(handle, "testing"); if(fn == NULL) { printf("%s\n", dlerror()); dlclose(handle); return 1; } dlclose(handle); return 0; } 

En parcourant le code avec le débogueur, je vois que le dlopen retourne un handle. Selon la page de manuel, If filename is NULL, then the returned handle is for the main program. Donc, si je lie un symbole appelé testing dans le programme principal, dlsym devrait le trouver, non?

Voici comment je comstack et relie le programme:

 all: test instr.o: instr.c gcc -ggdb -Wall -c instr.c test.o: test.c gcc -ggdb -Wall -c test.c test: test.o instr.o gcc -ldl -o test test.o instr.o clean: rm -f *.o test 

Et quand je construis ce programme, puis fais objdump -t test | grep testing objdump -t test | grep testing , je vois que le testing symbole est bien là:

 08048632 g F .text 00000020 testing 

Pourtant, la sortie de mon programme est l’erreur:

 ./test: undefined symbol: testing 

Je ne suis pas sûr de ce que je fais mal. J’apprécierais que quelqu’un puisse faire la lumière sur ce problème.

Je ne pense pas que vous puissiez le faire, dlsym fonctionne sur les symboles exportés. Comme vous faites dlsym sur NULL (image courante), même si les symboles sont présents dans l’image ELF exécutable, ils ne sont pas exportés (car ce n’est pas une bibliothèque partagée).

Pourquoi ne pas l’appeler directement et laisser l’éditeur de liens s’en occuper? Il est inutile d’utiliser dlsym pour obtenir des symboles de la même image que votre appel dlsym . Si votre symbole de testing trouvait dans une bibliothèque partagée que vous avez liée ou chargée à l’aide de dlopen vous pourrez le récupérer.

Je crois qu’il existe aussi un moyen d’exporter des symboles lors de la création d’exécutables ( -Wl,--export-dynamic comme mentionné dans un commentaire de Brandon), mais je ne sais pas pourquoi vous voulez le faire.