Dlopen Failed: Cannot Open Shared Object File: No Such File or Directory

dlopen failed: cannot open shared object file: No such file or directory

If the library you want to dlopen is not in the standard search path you have a number of options:

  1. Specify the full path to the file in dlopen

    dlopen("/full/path/to/libfile.so");

  2. Add the path to the library via LD_LIBRARY_PATH

    LD_LIBRARY_PATH=/path/to/library/ ./executable

  3. use the ld -rpath option to add a library path to the application.

    g++ -link stuff- -Wl,-rpath=/path/to/library/

Note that options 1 & 3 hardcode the library path into your application. -rpath does have an option to specify a relative path, i.e.

-Wl,-rpath=$ORIGIN/../lib/

Will embed a relative path into the application.

dlopen: libcrypt.so.1: cannot open shared object file: No such file or directory

Same thing happened to me today, this is what I did to fix it (Arcolinux 5.16.10-arch1-1)

Removed docker-compose

$ sudo rm -r /usr/local/bin/docker-compose

Reinstalled it using pip (was not working with the curl method)

$ sudo pip install docker-compose

Error loading shared libraries with dlopen()

What conditions could cause this behavior?

When you call dlopen("/path_to_plugin/libservices.so", ...), the loader does this:

  1. Open the given path, verify it's a suitable ELF file with correct architecture
  2. Read the dynamic section of that file. For each DT_NEEDED (libconfig.so here),
  3. Scan the list of already opened DSOs, looking for exact match (this fails for you),
    1. If found, increment reference count
    2. Else try to find the needed library on disk.

Since step 3 is failing for you, it's a pretty safe bet that something has corrupted the loader list of already opened DSOs, or someone called dlclose on libconfig.so.

If GDB info shared still lists libconfig.so at step 3, then it's the former. If it doesn't, then it's the latter.

You should be able to verify corruption by looking at _r_debug->r_map elements in GDB, and comparing the entries with GDB info shared output.

The first entries in that list will have the main executable, the VDSO, and directly-linked shared libraries (e.g. libc.so.6 and libdl.so.2). Then you should see the entry for libconfig.so, except its l_name will probably be mangled in some way.

If this is indeed the case, you can find who corrupts the loader list by setting a breakpoint on dlopen("/path/to/libconfig.so",...), verifying that the r_map is correct at that point, and then setting a watchpoint on the memory that gets corrupted later.

On the other hand if you have a rogue dlclose somewhere, then just setting a breakpoint on dlclose should quickly lead you to the problem.

Update:

I'm having a difficult time figuring out how to see the contents of _r_debug->r_map

There are two ways to get access to it:

  1. Install debuginfo packages for your GLIBC. On Ubuntu, apt-get install libc6-dbg should do, or
  2. Compile your program in such a way that the debug info for _r_debug is included in it. For example:

    cat t.c
    int main() { return 0; }

    gcc -g t.c && gdb -q ./a.out
    (gdb) start
    Temporary breakpoint 1 at 0x4004e1: file t.c, line 1.
    Starting program: /tmp/a.out

    Temporary breakpoint 1, main () at t.c:1
    1 int main() { return 0; }
    (gdb) p _r_debug
    $1 = 1 # The program does not reference _r_debug itself,
    # and debuginfo is not installed. This is probably what you see.

Let's fix that:

cat t2.c
#include <link.h>

int main() { return _r_debug.r_version; } // reference needed for debug info

gcc -g t2.c && gdb -q ./a.out
(gdb) start
Temporary breakpoint 1 at 0x400561: file t2.c, line 3.
Starting program: /tmp/a.out

Temporary breakpoint 1, main () at t2.c:3
3 int main() { return _r_debug.r_version; }
(gdb) p _r_debug
$1 = {r_version = 1, r_map = 0x7ffff7ffe1c8, r_brk = 140737351960640, r_state = RT_CONSISTENT, r_ldbase = 140737351884800}
(gdb) p _r_debug.r_map[0]
$2 = {l_addr = 0, l_name = 0x7ffff7df6c3d "", l_ld = 0x600e18, l_next = 0x7ffff7ffe758, l_prev = 0x0}

C++ linux: dlopen can't find .so library

Read the dlopen(3) man page (e.g. by typing man dlopen in a terminal on your machine):

If filename contains a slash ("/"), then it
is interpreted as a (relative or absolute) pathname. Otherwise, the
dynamic linker searches for the library as follows (see ld.so(8) for
further details):

   o   (ELF only) If the executable file for the calling program
contains a DT_RPATH tag, and does not contain a DT_RUNPATH tag,
then the directories listed in the DT_RPATH tag are searched.

o 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.)

o (ELF only) If the executable file for the calling program
contains a DT_RUNPATH tag, then the directories listed in that
tag are searched.

o The cache file /etc/ld.so.cache (maintained by ldconfig(8)) is
checked to see whether it contains an entry for filename.

o The directories /lib and /usr/lib are searched (in that order).

So you need to call dlopen("./libLibraryName.so", RTLD_NOW) -not just dlopen("libLibraryName.so", RTLD_NOW) which wants your plugin to be in your $LD_LIBRARY_PATH on in /usr/lib/ etc .... - or add . to your LD_LIBRARY_PATH (which I don't recommend for security reasons).

As Jhonnash answered you should use and display the result of dlerror when dlopen (or dlsym) fails:

  void* dlh = dlopen("./libLibraryName.so", RTLD_NOW);
if (!dlh)
{ fprintf(stderr, "dlopen failed: %s\n", dlerror());
exit(EXIT_FAILURE); };

You might want to read some books like Advanced Linux Programming to get some knowledge about Linux system programming in general.

Cannot dlopen a shared library from a shared library, only from executables

The most likely reason for dlopen from the main executable to succeed and for the exact same dlopen from libcore.so to fail is that the main executable has correct RUNPATH to find all the libraries, but libcore.so does not.

You can verify this with:

readelf -d main-exe | grep R.*PATH
readelf -d libcore.so | grep R.PATH

If (as I suspect) main-exe has RUNPATH, and libcore.so doesn't, the right fix is to add -rpath=.... to the link line for libcore.so.

You can also gain a lot of insight into dynamic loader operation by using LD_DEBUG envrironment variable:

LD_DEBUG=libs ./main-exe

will tell you which directories the loader is searching for which libraries, and why.

I cannot find out why it's not working

Yes, you can. You haven't spent nearly enough effort trying.

Your very first step should be to print the value of dlerror() when dlopen fails. The next step is to use LD_DEBUG. And if all that fails, you can actually debug the runtime loader itself -- it's open-source.

cannot open shared object file: No such file or directory

Your LD_LIBRARY_PATH doesn't include the path to libsvmlight.so.

$ export LD_LIBRARY_PATH=/home/tim/program_files/ICMCluster/svm_light/release/lib:$LD_LIBRARY_PATH

cannot open shared object file: No such file or directory | including libbpf with userspace program

You should add the libbpf library directory to your LD_LIBRARY_PATH variable.

$ LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/build/root/usr/lib64
$ export LD_LIBRARY_PATH

Then go ahead an run the program. Note that if you run it with sudo, you may also need to set root's LD_LIBRARY_PATH

$ sudo su
# LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/build/root/usr/lib64
# export LD_LIBRARY_PATH
# ./user

You can verify that libbfp was found with the same ldd command.



Related Topics



Leave a reply



Submit