Checking Shared Libraries for Non Default Loaders

checking shared libraries for non default loaders

Python, Perl, and other interpreted languages do load things dynamically using dlopen(). (This is not the same thing as replacing the standard loader; they are still using that, and in fact dlopen() is a hook into the standard loader on ELF-based systems.)

There is no standard registry for loadable modules. Python uses its own rules to determine where extension modules can be loaded from (look at sys.path), including those which have associated shared objects. Perl uses different rules. Apache uses still different rules, etc.

So to summarize the answers to your questions:

  1. not exactly

  2. no

How to show all shared libraries used by executables in Linux?

  1. Use ldd to list shared libraries for each executable.
  2. Cleanup the output
  3. Sort, compute counts, sort by count

To find the answer for all executables in the "/bin" directory:

find /bin -type f -perm /a+x -exec ldd {} \; \
| grep so \
| sed -e '/^[^\t]/ d' \
| sed -e 's/\t//' \
| sed -e 's/.*=..//' \
| sed -e 's/ (0.*)//' \
| sort \
| uniq -c \
| sort -n

Change "/bin" above to "/" to search all directories.

Output (for just the /bin directory) will look something like this:

  1 /lib64/libexpat.so.0
1 /lib64/libgcc_s.so.1
1 /lib64/libnsl.so.1
1 /lib64/libpcre.so.0
1 /lib64/libproc-3.2.7.so
1 /usr/lib64/libbeecrypt.so.6
1 /usr/lib64/libbz2.so.1
1 /usr/lib64/libelf.so.1
1 /usr/lib64/libpopt.so.0
1 /usr/lib64/librpm-4.4.so
1 /usr/lib64/librpmdb-4.4.so
1 /usr/lib64/librpmio-4.4.so
1 /usr/lib64/libsqlite3.so.0
1 /usr/lib64/libstdc++.so.6
1 /usr/lib64/libz.so.1
2 /lib64/libasound.so.2
2 /lib64/libblkid.so.1
2 /lib64/libdevmapper.so.1.02
2 /lib64/libpam_misc.so.0
2 /lib64/libpam.so.0
2 /lib64/libuuid.so.1
3 /lib64/libaudit.so.0
3 /lib64/libcrypt.so.1
3 /lib64/libdbus-1.so.3
4 /lib64/libresolv.so.2
4 /lib64/libtermcap.so.2
5 /lib64/libacl.so.1
5 /lib64/libattr.so.1
5 /lib64/libcap.so.1
6 /lib64/librt.so.1
7 /lib64/libm.so.6
9 /lib64/libpthread.so.0
13 /lib64/libselinux.so.1
13 /lib64/libsepol.so.1
22 /lib64/libdl.so.2
83 /lib64/ld-linux-x86-64.so.2
83 /lib64/libc.so.6

Edit - Removed "grep -P"

Linux: Why loader finds my shared library?

Perhaps your build process is setting RPATH inside your executable to look for the library in the same directory. To test this, try moving the executable to a different directory and see if you can run it (or ldd it) then.

You can also check for RPATH in an executable in either of these ways:

readelf -d the-exe | grep RPATH
objdump -x the-exe | grep RPATH

For more on this, see here: https://unix.stackexchange.com/questions/22926/where-do-executables-look-for-shared-objects-at-runtime

How to specify non-default shared-library path in GCC Linux? Getting error while loading shared libraries when running

There are two ways to achieve that:

  • Use -rpath linker option:

gcc XXX.c -o xxx.out -L$HOME/.usr/lib -lXX -Wl,-rpath=/home/user/.usr/lib

  • Use LD_LIBRARY_PATH environment variable - put this line in your ~/.bashrc file:

    export LD_LIBRARY_PATH=/home/user/.usr/lib

This will work even for a pre-generated binaries, so you can for example download some packages from the debian.org, unpack the binaries and shared libraries into your home directory, and launch them without recompiling.

For a quick test, you can also do (in bash at least):

LD_LIBRARY_PATH=/home/user/.usr/lib ./xxx.out

which has the advantage of not changing your library path for everything else.

What is the best way to look for ELF Shared Libraries under linux in C

/usr/lib64 and /lib64 for 64-bit binaries or /usr/lib and /lib for 32-bit binaries, than paths taken from /etc/ld.so.conf and included configs

From man ldconfig

ldconfig creates the necessary links and cache to the most recent shared libraries found in the directories specified on the command line, in the file /etc/ld.so.conf, and in the trusted directories, /lib and /usr/lib (on some 64-bit architectures such as x86-64, /lib and /usr/lib are the trusted directories for 32-bit libraries, while /lib64 and /usr/lib64 are used for 64-bit libraries).

The cache is used by the run-time linker, ld.so or ld-linux.so.

...

/etc/ld.so.conf File containing a list of directories, one per line, in which to search for libraries.

Note that this info is for openSUSE, other distros may use different paths.

How to load a shared library without loading its dependencies?

Well, variables are still resolved even with RTLD_LAZY, so in general you do need all the libraries to be linked. Seems like you should create a stub libbar.so.1 that has no functionality and can be found by the linker.

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.



Related Topics



Leave a reply



Submit