Suchpfade von dlopen()



  • Du kannst mit dem Programm strace gucken, welche Dateien versucht werden zu öffnen. Ansonsten überprüfe mal auf Tippfehler.



  • Hi,

    erstmal danke für die Antworten. Ich habe bereits mit export LD_DEBUG=files geschaut, aber da steht auch nur dass henon.so (die datei die ich laden will) die library libremote.so braucht, die dann nicht gefunden wird. die anderen optionen, wie LD_DEBUG=libs usw. funktionieren nicht, weil der code von matlab aus ausgeführt wird und matlab mit diesen optionen gar nicht erst startet.

    Ich habe die tatsächlichen Pfade aus Platzgründen weggelassen, aber wenn ihr sie sehen wollt:

    Opening /ag/agstuddellnitz/bderenor/pareto/svn/OptGaio/gaio/models/henon.so, LD_LIBRARY_PATH is now "/opt/matlab/matlab7.8/sys/os/glnx86:
    /opt/matlab/matlab7.8/bin/glnx86:/opt/matlab/matlab7.8/extern/lib/glnx86:
    /opt/matlab/matlab7.8/sys/java/jre/glnx86/jre/lib/i386/native_threads:
    /opt/matlab/matlab7.8/sys/java/jre/glnx86/jre/lib/i386/client:
    /opt/matlab/matlab7.8/sys/java/jre/glnx86/jre/lib/i386:
    /opt/matlab/matlab7.0sp2/bin/glnx86/:
    /ag/agstuddellnitz/bderenor/pareto/svn/OptGaio/gaio/lib:
    /ag/agstuddellnitz/bderenor/pareto/svn/OptGaio/gaio/models:
    /ag/agstuddellnitz/bderenor/pareto/svn/OptGaio/gaio/../schuetze/models:
    /ag/agstuddellnitz/bderenor/pareto/svn/OptGaio/gaio/externalLib/protobuf/lib:
    /ag/agstuddellnitz/bderenor/pareto/svn/OptGaio/gaio/externalLib/protobuf-c/lib"...
    Could not open shared object file: libremote.so: cannot open shared object file: No such file or directory

    Und hier das ls von dem im LD_LIBRARY_PATH oben offensichtlich enthaltenen Pfad:

    $ ls /ag/agstuddellnitz/bderenor/pareto/svn/OptGaio/gaio/lib
    libParetoMatrix.so libarpack.a libblas.a libgaio.a liblapack.a liblpk.a libremote.a libremote.so stNRg6Cl stazBJqc stgFitdy

    strace liefert an dieser Stelle gar keine Ausgabe (also matlab mit "strace matlab" gestartet und dann innerhalb matlab das prog ausgeführt).



  • Hi,

    ich habe jetzt mal alles was mit matlab zu tun hat aus dem code entfernt und ein testprogramm erzeugt das nichts anderes tut als zu versuchen henon.so zu laden. strace liefert hier diese (auf libremote.so bezogenen) Ausgaben:

    open("/lib/tls/i686/sse2/cmov/libremote.so", O_RDONLY) = -1 ENOENT (No such file or directory)
    open("/lib/tls/i686/sse2/libremote.so", O_RDONLY) = -1 ENOENT (No such file or directory)
    open("/lib/tls/i686/cmov/libremote.so", O_RDONLY) = -1 ENOENT (No such file or directory)
    open("/lib/tls/i686/libremote.so", O_RDONLY) = -1 ENOENT (No such file or directory)
    open("/lib/tls/sse2/cmov/libremote.so", O_RDONLY) = -1 ENOENT (No such file or directory)
    open("/lib/tls/sse2/libremote.so", O_RDONLY) = -1 ENOENT (No such file or directory)
    open("/lib/tls/cmov/libremote.so", O_RDONLY) = -1 ENOENT (No such file or directory)
    open("/lib/tls/libremote.so", O_RDONLY) = -1 ENOENT (No such file or directory)
    open("/lib/i686/sse2/cmov/libremote.so", O_RDONLY) = -1 ENOENT (No such file or directory)
    open("/lib/i686/sse2/libremote.so", O_RDONLY) = -1 ENOENT (No such file or directory)
    open("/lib/i686/cmov/libremote.so", O_RDONLY) = -1 ENOENT (No such file or directory)
    open("/lib/i686/libremote.so", O_RDONLY) = -1 ENOENT (No such file or directory)
    open("/lib/sse2/cmov/libremote.so", O_RDONLY) = -1 ENOENT (No such file or directory)
    open("/lib/sse2/libremote.so", O_RDONLY) = -1 ENOENT (No such file or directory)
    open("/lib/cmov/libremote.so", O_RDONLY) = -1 ENOENT (No such file or directory)
    open("/lib/libremote.so", O_RDONLY) = -1 ENOENT (No such file or directory)
    open("/usr/lib/tls/i686/sse2/cmov/libremote.so", O_RDONLY) = -1 ENOENT (No such file or directory)
    open("/usr/lib/tls/i686/sse2/libremote.so", O_RDONLY) = -1 ENOENT (No such file or directory)
    open("/usr/lib/tls/i686/cmov/libremote.so", O_RDONLY) = -1 ENOENT (No such file or directory)
    open("/usr/lib/tls/i686/libremote.so", O_RDONLY) = -1 ENOENT (No such file or directory)
    open("/usr/lib/tls/sse2/cmov/libremote.so", O_RDONLY) = -1 ENOENT (No such file or directory)
    open("/usr/lib/tls/sse2/libremote.so", O_RDONLY) = -1 ENOENT (No such file or directory)
    open("/usr/lib/tls/cmov/libremote.so", O_RDONLY) = -1 ENOENT (No such file or directory)
    open("/usr/lib/tls/libremote.so", O_RDONLY) = -1 ENOENT (No such file or directory)
    open("/usr/lib/i686/sse2/cmov/libremote.so", O_RDONLY) = -1 ENOENT (No such file or directory)
    open("/usr/lib/i686/sse2/libremote.so", O_RDONLY) = -1 ENOENT (No such file or directory)
    open("/usr/lib/i686/cmov/libremote.so", O_RDONLY) = -1 ENOENT (No such file or directory)
    open("/usr/lib/i686/libremote.so", O_RDONLY) = -1 ENOENT (No such file or directory)
    open("/usr/lib/sse2/cmov/libremote.so", O_RDONLY) = -1 ENOENT (No such file or directory)
    open("/usr/lib/sse2/libremote.so", O_RDONLY) = -1 ENOENT (No such file or directory)
    open("/usr/lib/cmov/libremote.so", O_RDONLY) = -1 ENOENT (No such file or directory)
    open("/usr/lib/libremote.so", O_RDONLY) = -1 ENOENT (No such file or directory)
    open("/lib/i486-linux-gnu/tls/i686/sse2/cmov/libremote.so", O_RDONLY) = -1 ENOENT (No such file or directory)
    open("/lib/i486-linux-gnu/tls/i686/sse2/libremote.so", O_RDONLY) = -1 ENOENT (No such file or directory)
    open("/lib/i486-linux-gnu/tls/i686/cmov/libremote.so", O_RDONLY) = -1 ENOENT (No such file or directory)
    open("/lib/i486-linux-gnu/tls/i686/libremote.so", O_RDONLY) = -1 ENOENT (No such file or directory)
    open("/lib/i486-linux-gnu/tls/sse2/cmov/libremote.so", O_RDONLY) = -1 ENOENT (No such file or directory)
    open("/lib/i486-linux-gnu/tls/sse2/libremote.so", O_RDONLY) = -1 ENOENT (No such file or directory)
    open("/lib/i486-linux-gnu/tls/cmov/libremote.so", O_RDONLY) = -1 ENOENT (No such file or directory)
    open("/lib/i486-linux-gnu/tls/libremote.so", O_RDONLY) = -1 ENOENT (No such file or directory)
    open("/lib/i486-linux-gnu/i686/sse2/cmov/libremote.so", O_RDONLY) = -1 ENOENT (No such file or directory)
    open("/lib/i486-linux-gnu/i686/sse2/libremote.so", O_RDONLY) = -1 ENOENT (No such file or directory)
    open("/lib/i486-linux-gnu/i686/cmov/libremote.so", O_RDONLY) = -1 ENOENT (No such file or directory)
    open("/lib/i486-linux-gnu/i686/libremote.so", O_RDONLY) = -1 ENOENT (No such file or directory)
    open("/lib/i486-linux-gnu/sse2/cmov/libremote.so", O_RDONLY) = -1 ENOENT (No such file or directory)
    open("/lib/i486-linux-gnu/sse2/libremote.so", O_RDONLY) = -1 ENOENT (No such file or directory)
    open("/lib/i486-linux-gnu/cmov/libremote.so", O_RDONLY) = -1 ENOENT (No such file or directory)
    open("/lib/i486-linux-gnu/libremote.so", O_RDONLY) = -1 ENOENT (No such file or directory)
    open("/usr/lib/i486-linux-gnu/tls/i686/sse2/cmov/libremote.so", O_RDONLY) = -1 ENOENT (No such file or directory)
    open("/usr/lib/i486-linux-gnu/tls/i686/sse2/libremote.so", O_RDONLY) = -1 ENOENT (No such file or directory)
    open("/usr/lib/i486-linux-gnu/tls/i686/cmov/libremote.so", O_RDONLY) = -1 ENOENT (No such file or directory)
    open("/usr/lib/i486-linux-gnu/tls/i686/libremote.so", O_RDONLY) = -1 ENOENT (No such file or directory)
    open("/usr/lib/i486-linux-gnu/tls/sse2/cmov/libremote.so", O_RDONLY) = -1 ENOENT (No such file or directory)
    open("/usr/lib/i486-linux-gnu/tls/sse2/libremote.so", O_RDONLY) = -1 ENOENT (No such file or directory)
    open("/usr/lib/i486-linux-gnu/tls/cmov/libremote.so", O_RDONLY) = -1 ENOENT (No such file or directory)
    open("/usr/lib/i486-linux-gnu/tls/libremote.so", O_RDONLY) = -1 ENOENT (No such file or directory)
    open("/usr/lib/i486-linux-gnu/i686/sse2/cmov/libremote.so", O_RDONLY) = -1 ENOENT (No such file or directory)
    open("/usr/lib/i486-linux-gnu/i686/sse2/libremote.so", O_RDONLY) = -1 ENOENT (No such file or directory)
    open("/usr/lib/i486-linux-gnu/i686/cmov/libremote.so", O_RDONLY) = -1 ENOENT (No such file or directory)
    open("/usr/lib/i486-linux-gnu/i686/libremote.so", O_RDONLY) = -1 ENOENT (No such file or directory)
    open("/usr/lib/i486-linux-gnu/sse2/cmov/libremote.so", O_RDONLY) = -1 ENOENT (No such file or directory)
    open("/usr/lib/i486-linux-gnu/sse2/libremote.so", O_RDONLY) = -1 ENOENT (No such file or directory)
    open("/usr/lib/i486-linux-gnu/cmov/libremote.so", O_RDONLY) = -1 ENOENT (No such file or directory)
    open("/usr/lib/i486-linux-gnu/libremote.so", O_RDONLY) = -1 ENOENT (No such file or directory)
    Could not open shared object file: libremote.so: cannot open shared object file: No such file or directory

    Soweit ich das sehen kann wird also tatsächlich nicht im Inhalt von LD_LIBRARY_PATH gesucht.



  • Also entweder du fügst alle Verzeichnisse für die libs zu der LD_LIBRARY_PATH hinzu (hast du das beim letzten mal auch gemacht?) oder du gibst einfach den vollständigen Pfad bei dlopen an. (bruahct die libremote noch andere "eigene" libs?) Veränderst du LD_LIBRARY_PATH im Program?



  • Hi,

    alle Verzeichnisse für die libs sind im LD_LIBRARY_PATH und wie man bei strace sehen kann wird keins der verzeichnisse die im LD_LIBRARY_PATH stehen tatsächlich untersucht. dlopen wird bereits mit dem vollständigen Pfad aufgerufen "/ag/agstuddellnitz/bderenor/pareto/svn/OptGaio/gaio/models/henon.so", die libremote ist bereits eine dependency.



  • Irgendwie kann ich das nicht recht nachvollziehen.
    Ich hab mal einen kleinen test erstellt. Was passiert da bei dir?

    #!/bin/sh
    
    touch lib.c
    
    gcc -shared -Wl,-soname,liba.so -o liba.so lib.c
    gcc -shared -Wl,-soname,libb.so -o libb.so lib.c -L. -la
    
    cat << EOF > testdlopen.c
    #include <stdio.h>
    #include <stdlib.h>
    #include <dlfcn.h>
    
    int main(int argc, char *argv[])
    {
            void *handle;
    
            printf("LD_LIBRARY_PATH=%s\n", getenv("LD_LIBRARY_PATH"));
    
            if (!(handle = dlopen("./libb.so", RTLD_LAZY))) {
                    printf("dlopen: %s\n", dlerror());
                    return 2;
            }
    
            printf("lib loaded\n");
    
            dlclose(handle);
    
            return 0;
    }
    EOF
    
    gcc -o testdlopen -Wall -ldl testdlopen.c
    
    ./testdlopen
    LD_LIBRARY_PATH="." ./testdlopen
    

    Es wird eine leere liba erstellt und eine libb, die liba braucht. Dann ein Programm das versucht libb zu laden, einmal mit und einmal ohne "." in LD_LIBRARY_PATH.



  • Hi,

    danke lagalopex, das hat schonmal geholfen. Also, wenn ich die richtigen Pfade in der Shell setze bevor ich das prog starte, dann klappt alles wie es soll. wenn ich die pfade allerdings mittels setenv innerhalb des Programms setze, dann nicht. Mache ich hier etwas falsch? Ich setze die Pfade mittels

    char* env = constructEnvironment();
    setenv("LD_LIBRARY_PATH", env, 1);
    

    wobei innerhalb von constructEnvironment der string zusammengeklebt wird. der ist auch so erstmal richtig und bleibt auch noch bestehen wenn das Program beendet wurde. Kann es sein dass innerhalb des Progs gesetzte Umgebungsvariablen das Programm selbst nicht beeinflussen weil es noch mit den alten Umgebungsvariablen gestartet wurde?



  • man: dlopen(3):
    If, at the time that the program was started, the environment variable LD_LIBRARY_PATH was defined to contain a colon-separated list of directories, then these are searched. (As a security measure this variable is ignored for set-user-ID and set-group-ID programs.)

    Also muss LD_LIBRARY_PATH bereits beim Programmstart gesetzt sein.

    Denn die Umgebung wird am Anfang ausgewertet und kann über einen dritten Parameter von main oder der globalen Variablen man: environ(7) ausgewertet werden, welche von setenv nichtmehr verändert werden.
    Ich weiß allerdings nicht, wie dlopen das macht.



  • Hm,

    okay, was würde man also tun wenn man mit dlopen verzeichnisse durchsuchen will, die zum Programmstart noch nicht feststehen? Gibt es eine Möglichkeit dlopen direkt Pfadangaben für die sekundär geladenen Libraries mitzugeben? Kann man z.B. diese DT_RPATH und DT_RUNPATH attribute zur Laufzeit setzen?



  • Du könntest LD_LIBRARY_PATH in deiner Umgebung speichern (entweder vom Benutzer oder gar ganz global). Du könntest auch die Verzeichnisse offiziell eintragen in der /etc/ld.so.conf.

    Oder du startest dein Programm halt immer mit dem passenden LD_LIBRARY_PATH davor.


Anmelden zum Antworten