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:
Specify the full path to the file in dlopen
dlopen("/full/path/to/libfile.so");
Add the path to the library via LD_LIBRARY_PATH
LD_LIBRARY_PATH=/path/to/library/ ./executable
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:
- Open the given path, verify it's a suitable ELF file with correct architecture
- Read the dynamic section of that file. For each
DT_NEEDED
(libconfig.so
here), - Scan the list of already opened DSOs, looking for exact match (this fails for you),
- If found, increment reference count
- 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:
- Install debuginfo packages for your GLIBC. On Ubuntu,
apt-get install libc6-dbg
should do, or 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
Linux /Bin/Sh Check If String Contains X
Debugging Shared Libraries Remotely with Gdb/Gdbserver
Split Delimited File into Smaller Files by Column
Initiating Dynamic Variables (Variable Variables) in Bash Shell Script
How to Install Haskell Platform on Linux Debian Wheezy
Is There a Simple Way to Batch Rename Symlink Targets
Some Details on Arm Linux Boot
How to Kill All Child Processes Without Killing the Parent
Linux - List of Registered Devices
How to Produce Stand Alone Haskell Executable
Best Text Search Engine for Integrating with Custom Web App
Having Trouble Finding the Method _Kernel_Vsyscall Within the Linux Kernel
How to Measure the Stack Size of a Process
How to Write to Tty from a Kernel Module
Why Does Docker Prompt "Permission Denied" When Backing Up the Data Volume