Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

POSIX C Discussion :

threads et librairies dynamiques


Sujet :

POSIX C

  1. #1
    Membre à l'essai
    threads et librairies dynamiques
    Bonjour à tous,

    Un petit post pour vous expliquer mon problème du moment qui commence à sérieusement me tordre le cerveau.
    Je suis entrain de réalisé un programme qui est découpé comme ceci :
    J'ai un programme principal qui se charge de créer deux threads et de les lancer. Ces deux threads sont sensées simulées un système de navigation complexe. Chaque thread ouvre une librairie dynamique (dlopen, dlsym) et lance la fonction principale grâce au symbole récupéré.

    Travaillant à la base sous Solaris (donc UNIX), mes variables globales étaient déclarées dans mon programme principal. Dans mes librairies dynamiques, elles étaient déclarées en "extern". Quand je regardais le symbole d'une de ces variables, ça me donnait (pour une des libraires et pour mon prog principal) :
    > nm lib1.so | grep SYMBOL_A
    U SYMBOL_A
    > nm MON_PROG | grep SYMBOL_A
    002e88f0 B SYMBOL_A

    De cette façon, je n'avais aucun problème lors de l'exécution.

    Je suis passé depuis sous Linux (fedora core 6). Je recompile, je recréé mes librairie. Seulement dorénavant, mon programme plante et me ressort un "undefined symbol SYMBOL_A" sachant que tout est fait de la même façon.

    Pour info mes librairies sont créés comme ceci :
    ld -g -G -ashared -Bdynamic --export-dynamic -o lib1.so MA_LISTE_DE_.a -lm

    Je compile avec ces options : -g -D_REENTRANT -lpthread -lrt -ldl -lgcc_s

    Je bute un peu là-dessus et c'est vraiment dommage car je n'avais aucun souci auparavant. Y a t'il une option qui aurait bougé entre Linux et UNIX sur l'edition de mes liens ? Je cherche désespérement une piste.

  2. #2
    Membre émérite
    Tu as essayé d'ajouter "-u SYMBOL_A" lors de l'édition de liens de ta lib ?

  3. #3
    Membre à l'essai
    Ca ne change rien. Mon symbole était déjà undefined, et se trouvait bien dans la table des symboles de ma librairie vu que je l'ai déclaré en "extern" dedans. Me semble que c'est ma compilation qui ne fait pas le travail de la même façon. Sous Sun, elle arrivait à faire le lien entre la variable définie dans mon programme principal et le symbole indefini de ma librairie. Sur Linux, elle n'y arrive pas ... et je n'ai aucune idée pourquoi ...
    pour info, je compile avec gcc.

  4. #4
    Membre émérite
    Le message "undefined symbol SYMBOL_A", il te le donne au moment où tu fais le dlopen(), c'est ça ?

  5. #5
    Membre à l'essai
    Oui tout à fait. Je veux récupérer le symbole d'une fonction pour l'exécuter. Cette fonction utilise le SYMBOL_A.
    Dans le code ça donne :
    Channel_A = dlopen("./lib1.so.L",RTLD_NOW);
    if(Channel_A == NULL)
    printf("Channel_A dlerror %s\n", dlerror());

    Et à l'exécution j'ai :
    Channel_A dlerror ./libAFCS1.so.L: undefined symbol: SYMBOL_A


    Je trouve ça étrange que UNIX ait accepté d'ouvrir la librairie alors que LINUX me jette. Ca me fait penser que je vais regarder les options de dlopen(), on ne sait jamais ...

    EDIT : en comparant les man de dlopen() sur UNIX et Linux, en particulier l'option RTLD_NOW, je tombe sur ceci :
    pour Linux : If this value is specified, or the environment variable LD_BIND_NOW is set to a non-empty string, all undefined symbols in the library are resolved before dlopen() returns. If this can-not be done, an error is returned.

    Pour UNIX : All necessary relocations are performed when the object is first loaded. This process might waste some processing if relocations are performed for lazy references that are never used. However, this mode ensures that when an object is loaded, all symbols referenced during execution are available. This behavior mimics the loading of dependencies when the environment variable LD_BIND_NOW is in effect.

    Ceci explique donc mes différences de comportement. Il ne me reste plus qu'à trouver une solution... Merci en tout cas de m'avoir redonner un espoir de solution !

  6. #6
    Membre émérite
    Je crois qu'il faut que tu link aussi ton exécutable (et pas seulement ta lib) avec --export-dynamic. Le man de dlopen() dit :


    External references in the library are resolved using the libraries in
    that library's dependency list and any other libraries previously
    opened with the RTLD_GLOBAL flag. If the executable was linked with
    the flag "-rdynamic" (or, synonymously, "--export-dynamic"), then the
    global symbols in the executable will also be used to resolve refer‐
    ences in a dynamically loaded library
    .

  7. #7
    Membre à l'essai
    Je crois qu'il faut que tu link aussi ton exécutable (et pas seulement ta lib) avec --export-dynamic. Le man de dlopen() dit :
    Je crois que je te tire mon chapeau. Je n'ai plus de problème d'undefined, il reste quelques soucis mais qui ont l'air de venir d'ailleurs. Il me semble donc que ce problème est résolu. L'heure du week end arrive, je finirai de valider tout cela lundi je pense mais déjà merci beaucoup pour ton aide.