LD_LIBRARY_PATH working but LD_PRELOAD not working - c

I have 2 files: ./a.out and libasm.so,
I can execute by using LD_LIBRARY_PATH without any problem:
$> export LD_LIBRARY_PATH=$PWD
$> ./a.out
42
But, if I reset the LD_LIBRARY_PATH and I use LD_PRELOAD, it doesn't work anymore:
$> export LD_LIBRARY_PATH=
$> LD_PRELOAD=./libasm.so ./a.out
./a.out: error while loading shared libraries: libasm.so: cannot open shared object file: No such file or directory
What should I do to fix that problem ? I must use LD_PRELOAD to make it works (and no LD_LIBRARY_PATH)
The compilation is as below:
$> gcc main.c -L. -lasm
And the library has been created with the following command:
$> nasm -f elf64 strlen.S -o strlen.o && gcc -shared strlen.o -o libasm.so
ldd command gives the following:
$> ldd ./a.out
linux-vdso.so.1 (0x00007ffdda9fe000)
/home/Nicolas/rendu/Assembleur/asm_minilibc/libasm.so (0x00007fb468f28000)
libasm.so => not found
libc.so.6 => /lib64/libc.so.6 (0x00007fb468b48000)
/lib64/ld-linux-x86-64.so.2 (0x0000555c0b2dd000)
$> ldd /home/Nicolas/rendu/Assembleur/asm_minilibc/libasm.so
linux-vdso.so.1 (0x00007fffe09bc000)
libc.so.6 => /lib64/libc.so.6 (0x00007fb3390c2000)
/lib64/ld-linux-x86-64.so.2 (0x000055789183a000)
$> ls -l /home/Nicolas/rendu/Assembleur/asm_minilibc/libasm.so
-rwxrwxr-x. 1 Nicolas Nicolas 7728 18 mars 14:24 /home/Nicolas/rendu/Assembleur/asm_minilibc/libasm.so
Two lines refers to libasm.so, the first one is correctly found, but the second one is not found. Why is there 2 lines instead of one ?
Thank you very much,

Related

Getting "cannot open shared object file" even though ldd shows it can find it

I looked for similar post on this topic but none the solutions work for me. I am trying to build a small program using openssl.
/mnt/sda1/openssl$ gcc tstsvr.c -I/mnt/sda1/openssl/include -L/mnt/sda1/openssl -lcrypto -lssl
When I try to run it:
$ sudo ./a.out
./a.out: error while loading shared libraries: libcrypto.so.81.1.1: cannot open shared object file: No such file or directory
But:
$ ldd a.out
linux-vdso.so.1 (0x00007fff23fe6000)
libcrypto.so.81.1.1 => /mnt/sda1/openssl/libcrypto.so.81.1.1 (0x00007f82f1db9000)
libssl.so.81.1.1 => /mnt/sda1/openssl/libssl.so.81.1.1 (0x00007f82f1d1e000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f82f1b1a000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f82f1b14000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f82f1af1000)
/lib64/ld-linux-x86-64.so.2 (0x00007f82f20ad000)
Format looks fine (inside /mnt/sda1/openssl):
$ file a.out
a.out: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=760dc5f7be4f51f598bab38a0b1eab1a42ef8a68, for GNU/Linux 3.2.0, not stripped
$ file libcrypto.so.81.1.1
libcrypto.so.81.1.1: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=404d1e7ed143383801efbb10ed7914f2cd0858d4, not stripped
$ ldd libcrypto.so.81.1.1
linux-vdso.so.1 (0x00007ffc44b5a000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f1083a8c000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f1083a69000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f1083877000)
/lib64/ld-linux-x86-64.so.2 (0x00007f1083d93000)
Just to make sure, I added path to LD_LIBRARY_PATH as well. Even ran sudo ldconfig. Neither made any difference.
What else can I try?
Per sudoers(5):
By default, the env_reset flag is enabled. This causes commands to be executed with a new, minimal environment.
...
Note that the dynamic linker on most operating systems will remove variables that can control dynamic linking from the environment of set-user-ID executables, including sudo. Depending on the operating system this may include RLD*, DYLD, LD_, LDR_*, LIBPATH, SHLIB_PATH, and others. These type of variables are removed from the environment before sudo even begins execution and, as such, it is not possible for sudo to preserve them.
Your easiest option is probably to do:
sudo LD_LIBRARY_PATH=/mnt/sda1/openssl ./a.out

Issue with dynamic libraries

I've compiled source file on host-machine:
g++ -I./source/utils -m32 ./source/services/library_version_info.cpp -o version_info $DAALROOT/lib/ia32_lin/libdaal_core.so $DAALROOT/lib/ia32_lin/libdaal_thread.so -ltbb -liomp5 -lpthread -ldl
# echo $DAALROOT
# /opt/intel/compilers_and_libraries_2016.3.210/linux/daal/
When I'm trying to invoke this on target-machine I get such error:
./version_info: error while loading shared libraries: /opt/intel/compilers_and_libraries_2016.3.210/linux/daal/lib/ia32_lin/libdaal_core.so: cannot open shared object file: No such file or directory
# echo $DAALROOT
# /media/sdcard/daalroot/daal
$LD_LIBRARY_PATH on target-machine contains path to libdaal_core.so, but program does not see that. How can I fix this error?
upd. host g++: 5.4.0, target: 4.9.1
upd2.
ldd version_info
linux-gate.so.1 (0xb77db000)
/opt/intel/compilers_and_libraries_2016.3.210/linux/daal/lib/ia32_lin/libdaal_core.so => not found
/opt/intel/compilers_and_libraries_2016.3.210/linux/daal/lib/ia32_lin/libdaal_thread.so => not found
libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x4332e000)
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x43221000)
libc.so.6 => /lib/libc.so.6 (0x42e7d000)
libm.so.6 => /lib/libm.so.6 (0x43003000)
/lib/ld-linux.so.2 (0x42e50000)
env LD_DEBUG=all ./version_info
408:
408: file=/opt/intel/compilers_and_libraries_2016.3.210/linux/daal/lib/ia32_lin/libdaal_core.so [0]; needed by ./version_info [0]
./version_info: error while loading shared libraries: /opt/intel/compilers_and_libraries_2016.3.210/linux/daal/lib/ia32_lin/libdaal_core.so: cannot open shared object file: No such file or directory
echo $LD_LIBRARY_PATH
/media/sdcard/daalroot/daal/lib/ia32_lin:/media/sdcard/daalroot/daal/../tbb/lib/ia32_lin/gcc4.4
Solution:
g++ -I./source/utils -m32 ./source/services/library_version_info.cpp -o version_info -l daal_core -l daal_thread -ltbb -liomp5 -lpthread -ldl

cannot open shared object file: No such file or directory error while there is file

I try to create shared library and compile my main.c with this library
I follow this web site : http://www.yolinux.com/TUTORIALS/LibraryArchives-StaticAndDynamic.html
I give these commands :
gcc -fPIC -c *.c
gcc -shared -Wl,-rpath,/opt/lib -Wl,-soname,libctest.so.1 -o libctest.so.1.0 *.o
sudo mv libctest.so.1.0 /opt/lib
sudo ln -sf /opt/lib/libctest.so.1.0 /opt/lib/libctest.so
sudo ln -sf /opt/lib/libctest.so.1.0 /opt/lib/libctest.so.1
gcc -Wall -L/opt/lib main.c -lctest -o prog
Commands gave no error. When I execute binary file ./prog it gives ./prog: error while loading shared libraries: libctest.so.1: cannot open shared object file: No such file or directory
but libctest.so.1 is in /opt/lib
lrwxrwxrwx 1 root root 24 Aug 18 17:06 libctest.so -> /opt/lib/libctest.so.1.0
lrwxrwxrwx 1 root root 24 Aug 18 17:06 libctest.so.1 -> /opt/lib/libctest.so.1.0
-rwxr-xr-x 1 user user 7064 Aug 18 17:05 libctest.so.1.0
Also ldd prog is
linux-vdso.so.1 (0x00007ffe0f559000)
libctest.so.1 => not found
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fcd27fc6000)
/lib64/ld-linux-x86-64.so.2 (0x00007fcd28371000)
so what is wrong ?
I used debian 8.5 and gcc 4.9.2
GCC's ld command has an --rpath option that may solve your problems:
-rpath=dir
Add a directory to the runtime library search path.
You should add the location of your compiled library to GCC's command line when you compile prog, via the -wl option:
-Wl,option
Pass option as an option to the linker. If option contains commas,
it is split into multiple options at the commas.
So your search path already includes /opt/lib because of the original creation of the library:
-Wl,-rpath,/opt/lib
For the second compile, add the location of libctest.so.1.0 as another rpath, and it should be found without your needing to move files around:
gcc -Wall -L/opt/lib main.c -lctest -Wl,-rpath,/you/dir/name -o prog
I think your original effort is failing as the linker has included a hard path to your original outout dir, and then you moved the library from under it.
Try adding /opt/lib to LD_LIBRARY_PATH as below;
LD_LIBRARY_PATH=/opt/lib
I have a same proplem with iccxml
iccToXml profile.icc profile.xml
When i convert *.icc to *.xml by above code, i recived same message: cannot open shared object file: No such file or directory, Detail:
iccToXml: error while loading shared libraries: libIccXML.so.2: cannot open shared object file: No such file or directory
I resolved by use this command before convert
export LD_LIBRARY_PATH="/usr/local/lib"
You can replace "/usr/local/lib" by path of application file that you want.
Wish that is should helpfull for you.

Linux linking a shared object

I am linking an so, that depends on libmxml.so. However I have no rights install libmxml.so.
So thats what I am doing
gcc -shared -m32 -o ServiceProvider.so ServiceProvider.o -L ../../../../system/addonlibs/ -lmxml -lpthread
ldd shows me
ldd ServiceProvider.so
libmxml.so.1 => not found
libpthread.so.0 => /lib/libpthread.so.0 (0x40026000)
libc.so.6 => /lib/libc.so.6 (0x40046000)
the second try was
gcc -shared -m32 -o ServiceProvider.so ServiceProvider.o ../../../../system/addonlibs/libmxml.so -lpthread
and still ldd shows me
ldd ServiceProvider.so
libmxml.so.1 => not found
libpthread.so.0 => /lib/libpthread.so.0 (0x40026000)
libc.so.6 => /lib/libc.so.6 (0x40046000)
Consequently, ldd does not find the library, since I only have "libmxml.so", but no "libmxml.so.1". How do I get rid of this ".1" suffix? Why is it comming?
When you link with a dynamic library, you should not do :
gcc -shared -m32 -o ServiceProvider.so ServiceProvider.o ../../../../system/addonlibs/libmxml.so -lpthread
Instead, make sure that /yourpath/system/addonlibs (you should use the full path instead of a relative one) is in you LIBRARY_PATH. Then change you link command.
export LIBRARY_PATH=/yourpath/system/addonlibs:$LIBRARY_PATH
gcc -shared -m32 -o ServiceProvider.so ServiceProvider.o -lmxml -lpthread
You can also write that:
gcc -shared -m32 -o ServiceProvider.so ServiceProvider.o -L/yourpath/system/addonlibs -lmxml -lpthread
However, to run your program, you will need to have your library path in LD_LIBRARY_PATH.
If you have issues with .soand .so.1 stuff, then rename your .so to .so.1 and make a symlink from .so.1 to .so.
Edit:
If you do objdump -p libmxml.so | grep SONAME you will probably get libmxml.so.1.
It is where you get the libmxml.so.1 identifier.

C - Compile static file

I want to compile C code into one monolithic executable file (include every dependencies in this file) using GCC.
Usually I can compile the code with this command:
gcc -o server ex-serv-x509.c -lgnutls
But when I try to compile it with this -static argument I get this error:
[root#localhost test]# gcc -static -o server ex-serv-x509.c -lgnutls
/usr/bin/ld: cannot find -lc
collect2: ld returned 1 exit status
[root#localhost test]#
How I can solve the problem?
Best wishes
Try using the ldd command to see what it's linking in without the -static option. Here's what I get for a silly program I have.
~$ gcc so.o -lm -o so
~$ ldd so
linux-gate.so.1 => (0x00db7000)
libm.so.6 => /lib/libm.so.6 (0x00c7f000)
libc.so.6 => /lib/libc.so.6 (0x0037f000)
/lib/ld-linux.so.2 (0x002da000)
~$ gcc so.o -static -lm -o so
~$ ldd so
not a dynamic executable
So without the static I automagically get the shared version of libc, which surprised me even though it should not have. I imagine you have the shared version but not the static, so you'll need to get the static library from somewhere if you have decided that 1986 is the year for you :-).
To make sure you can do: gcc -print-search-dirs and search through them and make sure that libc.a is not to be found.

Resources