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.