IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
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

Linux Discussion :

Pb : Modification dynamique du LD_LIBRARY_PATH pour dlopen()


Sujet :

Linux

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    58
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2004
    Messages : 58
    Par défaut Pb : Modification dynamique du LD_LIBRARY_PATH pour dlopen()
    Bonjour,

    Voilà mon problème. Je fais un petit programme qui reçoit en entrée un ficher XML contenant entre autres une liste de librairies (.so) à charger.
    Ce fichier contient également le ou les répertoires dans le(s)quel(s) on peut trouver ces librairies.
    Un exemple de fichier :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    <Appli>
     <LibDir mode="relative" name="./Lib" />
     <LibDir mode="absolute" name="/home/noodles/Lib" />
     <Dependency lib="action1.so" />
     <Dependency lib="action2.so" /> 
    </Appli>
    Mon programme parse ce petit fichier, puis tente de charger dynamiquement les librairies.

    Ma première idée était que le programme rajoute dans la variable d'environnement LD_LIBRARY_PATH les chemins fournis, pour pouvoir charger les librairies.
    J'ai donc procédé comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    string ld = "LD_LIBRARY_PATH=";
    string oldPath = getenv("LD_LIBRARY_PATH");
    if(strlen(oldPath))
    {
      ld += oldPath;
      ld += ":";
    }
    ld += libDir; //libDir parsé depuis le XML
    if (putenv(const_cast<char *>(ld.c_str())) == -1)
      printf("putenv failed \n");
    Ce code marche bien (j'ai vérifié en faisant getenv("LD_LIBRARY_PATH")). Mais quand je fais dlopen(), il me dit qu'il ne trouve pas la librairie, comme si le nouveau LD_LIBRARY_PATH n'était pas pris en compte. Après quelques recherches, j'ai l'impression que le programme charge les variables d'environnement à son lancement, et donc ne les met pas à jour.

    J'ai même essayé d'aller voir ce qu'il y a dans la variable gloable char** environ après le putenv, et les modifications sont prises en compte!
    Donc je ne comprends pas trop!

    Je me suis donc dis que j'allais mettre directement dans le XML, les chemins complets des librairies. Malheureusement, cela ne marche pas non plus parce que quand dlopen() essaie de resoudre les dépendances, il n'y a pas ce qu'il faut dans le LD_LIBRARY_PATH!


    Donc pour résumer, ma question est : peut-on en C (ou C++), modifier la variable LD_LIBRARY_PATH qui est prise en compte par dlopen() pour ajouter des chemins à prendre en compte...

    Merci

    Noodles

  2. #2
    Expert confirmé

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Par défaut
    Ok tu as deux solutions :

    - Prendre tous tes répertoires et ajouter dans le xterm tes répertoires dans LD_LIBRARY_PATH.

    - Lancer ton programme avec tes dlopen et voir si cela passe.

    Je te dis cela puisque j'utilise putenv tous les jours et cela fonctionne très bien chez moi donc je ne vois pas pourquoi cela ne fonctionnerait pas chez toi.

    Jc

  3. #3
    Membre Expert
    Inscrit en
    Décembre 2004
    Messages
    1 478
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 478
    Par défaut
    EDIT: l'exemple donne ici est incorrect, cf. la reponse de fearyourself qui suit.

    Voici un petit exemple en C qui force LD_LIBRARY_PATH a ne contenir que /usr/lib et accede ensuite a libm.so sans lui donner le chemin complet (contrairement a ce que je disais dans le forum C, si le chemin n'est pas complet, dlopen() utilise effectivement LD_LIBRARY_PATH).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <dlfcn.h>
     
    /*
     * gcc -W -Wall -pedantic -rdynamic so.c -o so -ldl
     *
     *
     * overwrite environment variable LD_LIBRARY_PATH
     * with a single directory.
     */
    static int force_library_path(const char *path)
    {
      int ret = -1; /* error code */
      char keyval[100];
      const char *envvar = "LD_LIBRARY_PATH";
      int status;
     
      sprintf(keyval, "%s= %s", envvar, path);
      status = putenv(keyval);
      if (status == 0)
      {
        /*
         * print the new value of envvar
         */
        char *pathv = getenv(envvar);
     
        if (pathv != NULL)
        {
          printf("Value of %s is %s.\n", envvar, pathv);
          ret = 0; /* success */
        }
      }
     
      return ret;
    }
     
    int main(void)
    {
      int ret = EXIT_FAILURE;
     
      int status = force_library_path("/usr/lib");
     
      if (status != 0)
      {
        fprintf(stderr, "Failed to force library path.\n");
      }
      else
      {
        void *handle;
     
        handle = dlopen ("libm.so", RTLD_LAZY);
        if (handle == NULL)
        {
          fprintf(stderr, "%s\n", dlerror());
        }
        else
        {
          double (*cosine)(double);
          char *error;
     
          cosine = dlsym(handle, "cos");
          error = dlerror();
          if(error != NULL)
          {
            fprintf(stderr, "%s\n", error);
          }
          else
          {
            printf("%f\n", cosine(2.0));
            dlclose(handle);
            ret = EXIT_SUCCESS;
          }
        }
      }
     
      return ret;
    }
    Comme prevu, la sortie produite est:
    Value of LD_LIBRARY_PATH is /usr/lib.
    -0.416147
    Donc l'appel a putenv() met bien a jour la variable d'environnement pour la suite du programme. Ton probleme doit venir d'ailleurs.

  4. #4
    Expert confirmé

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Par défaut
    Citation Envoyé par DaZumba
    Donc l'appel a putenv() met bien a jour la variable d'environnement pour la suite du programme. Ton probleme doit venir d'ailleurs.

    Désolé mais cela ne prouve rien. dlopen regardera de toute facon dans /lib et /usr/lib s'il ne trouve pas ce qu'il cherche.

    Donc mettre /usr/lib dans LD_LIBRARY_PATH provoque simplement un changement dans l'ordre de recherche dans les répertoire.

    [EDIT]D'ailleurs je viens de tester avec une bibliothèque dynamique perso et ton code ne fonctionne pas. Cela semble plus compliquer que ce qu'on peut croire...[/EDIT]
    Jc

  5. #5
    Membre Expert
    Inscrit en
    Décembre 2004
    Messages
    1 478
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 478
    Par défaut
    Citation Envoyé par fearyourself
    Désolé mais cela ne prouve rien. dlopen regardera de toute facon dans /lib et /usr/lib s'il ne trouve pas ce qu'il cherche.
    Ah oui c'est une bonne remarque, cela. Je modifie mon post pour prevenir qu'il est incorrect.

    D'ailleurs je viens de tester avec une bibliothèque dynamique perso et ton code ne fonctionne pas. Cela semble plus compliquer que ce qu'on peut croire...
    En effet. Je viens de tester avec une biblio perso egalement, placee dans /tmp, et ecraser LD_LIBRARY_PATH pour y mettre /tmp ne permet pas a dlopen() de trouver ma biblio. Par contre, faire un export LD_LIBRARY_PATH=/tmp avant de faire tourner le programme arrange les choses, comme Noodles l'avait fait remarquer. Malheureusement, la manpage de dlopen() chez moi n'est pas tres explicite:
    Citation Envoyé par man dlopen
    The file argument is used to construct a pathname to the object file. If file contains a slash character, the file argument is used as the pathname for the file. Otherwise, file is used in an implementation-defined manner to yield a pathname.
    Mouais. Je ne fais pas avancer le truc...

  6. #6
    Membre Expert
    Inscrit en
    Décembre 2004
    Messages
    1 478
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 478
    Par défaut
    Ok, apres un petit coup de Google, il semble que putenv() ne met en effet pas a jour l'environnement dans lequel le programme evolue (c'est apparemment impossible). Par contre, elle permet d'installer un environnement avant d'appeler un autre programme (via execlp() par exemple). J'aurais appris quelque-chose au moins !

Discussions similaires

  1. Réponses: 5
    Dernier message: 01/08/2007, 20h31
  2. Modification dynamique de la couche alpha
    Par Daedar dans le forum OpenGL
    Réponses: 6
    Dernier message: 22/10/2005, 14h22
  3. [JTree] Modification dynamique du texte à afficher
    Par jIdJo dans le forum Composants
    Réponses: 2
    Dernier message: 17/06/2005, 16h49
  4. Réponses: 12
    Dernier message: 26/04/2004, 08h32

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo