I need to list the programs which have a specified shared library linked to them in UNIX/Linux (like ldd but vice versa)
I highly doubt there would be. That would require keeping a database of all executables and remembering what they depend on, which may be possible if you only install software from a specific channel, but it certainly won't be able to track executables you produce otherwise. Not to mention such a database is largely useless and therefore not attractive.
If you need to find such executables however (e.g. to know if it's safe to remove the shared library), you can easily find most of them. The key is that most of the executables you have are inside /usr/bin
or /usr/local/bin
or similar locations. So all you need is to run ldd
on all files inside those directories and grep
for the library you are looking for.
Is there a C++ API Linux System call that tells you which shared libraries your executable has linked?
You can use dl_iterate_phdr:
#define _GNU_SOURCE
#include <link.h>
#include <stdlib.h>
#include <stdio.h>
static int callback(struct dl_phdr_info *info, size_t size, void *data) {
printf("name=%s (%d segments)\n", info->dlpi_name, info->dlpi_phnum);
return 0;
}
int main() {
dl_iterate_phdr(callback, NULL);
return 0;
}
This program will produce the following output:
name= (9 segments)
name= (4 segments)
name=/lib64/libdl.so.2 (7 segments)
name=/lib64/libc.so.6 (10 segments)
name=/lib64/ld-linux-x86-64.so.2 (7 segments)
How to check shared library version in the binary
I use dl_iterate_phdr function to find out which shared objects are loaded. This is example of dl handler that prints shared libs info
static int header_handler(struct dl_phdr_info* info, size_t size, void* data)
{
printf("name=%s (%d segments) address=%p\n",
info->dlpi_name, info->dlpi_phnum, (void*)info->dlpi_addr);
for (int j = 0; j < info->dlpi_phnum; j++) {
printf("\t\t header %2d: address=%10p\n", j,
(void*) (info->dlpi_addr + info->dlpi_phdr[j].p_vaddr));
printf("\t\t\t type=%u, flags=0x%X\n",
info->dlpi_phdr[j].p_type, info->dlpi_phdr[j].p_flags);
}
printf("\n");
return 0;
}
It is taken from here
It prints for my video processing project following :
name=/usr/local/lib/libopencv_highgui.so.2.4 (7 segments) address=0x7f467935a000
name=/usr/local/lib/libopencv_imgproc.so.2.4 (7 segments) address=0x7f46796e9000
...
Opencv includes the version in the name of library libopencv_imgproc.so*.2.4* .
This way i know wich opencv version loaded. I don't know if it is good for your libraries, but it can be a starting point for your.
Why don't the programs implemented by Golang use the functions of libc.so.6, such as socket()?
Why don't the programs implemented by Go[...] use the functions of libc.so.6.
Because Go uses direct syscalls to the underlying OS.
Tracing linked libraries
Actually ldd
gives you absolute path with filename of whatever from your application's shared library dependencies it's able to find.
$ ldd v8test
linux-gate.so.1 => (0xb78b2000)
libz.so.1 => /usr/lib/libz.so.1 (0xb787e000)
librt.so.1 => /lib/i686/cmov/librt.so.1 (0xb7875000)
libcppunit-1.12.so.1 => /usr/lib/libcppunit-1.12.so.1 (0xb782c000)
libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0xb7604000)
libm.so.6 => /lib/i686/cmov/libm.so.6 (0xb75dd000)
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0xb75bf000)
libc.so.6 => /lib/i686/cmov/libc.so.6 (0xb7478000)
libpthread.so.0 => /lib/i686/cmov/libpthread.so.0 (0xb745f000)
libboost_system-mt.so.1.38.0 => /usr/lib/libboost_system-mt.so.1.38.0 (0xb745b000)
/lib/ld-linux.so.2 (0xb78b3000)
libdl.so.2 => /lib/i686/cmov/libdl.so.2 (0xb7456000)
libboost_thread-mt.so.1.38.0 => /usr/lib/libboost_thread-mt.so.1.38.0 (0xb7383000)
libboost_filesystem-mt.so.1.38.0 => /usr/lib/libboost_filesystem-mt.so.1.38.0 (0xb7370000)
libtinyxml.so.1 => /home/dmitry/tinyxml/libtinyxml.so.1 (0xb7359000)
libboost_regex-mt.so.1.38.0 => /usr/lib/libboost_regex-mt.so.1.38.0 (0xb728c000)
libmysqlclient_r.so.15 => /usr/lib/libmysqlclient_r.so.15 (0xb70a1000)
libicuuc.so.42 => /usr/lib/libicuuc.so.42 (0xb6f61000)
libicudata.so.42 => /usr/lib/libicudata.so.42 (0xb601a000)
libicui18n.so.42 => /usr/lib/libicui18n.so.42 (0xb5e6b000)
libcrypt.so.1 => /lib/i686/cmov/libcrypt.so.1 (0xb5e39000)
libnsl.so.1 => /lib/i686/cmov/libnsl.so.1 (0xb5e22000)
The libraries are searched by its soname (e.g. libboost_filesystem-mt.so.1.38.0) in paths mentioned in /etc/ld.so.conf
, LD_LIBRARY_PATH
or set with rpath
in the binary itself.
If ldd
is unable to find something it will look like
libicuuc.so.42 => not found
In this case consider using one of the mentioned ways to give correct search path.
ldd
will warn you when it's unable to load the library due to some reason.
$ ldd v8test
./v8test: error while loading shared libraries: /home/dmitry/a/liba.so.2: invalid ELF header
Of course it can't protect you from the errors in the library itself. In fact it's possible your application to depend on libraries A and B, both depending on incompatible versions on some library C. In this situation your program has a good chance to crash (unless library C doesn't have symbol versioning) - ldd is not going to warn you, but you should be able to see it in the output.
Program-Library-HOWTO will be useful for you.
Check also some options of ldd
or dynamic linker.
Do libraries reported by ldd resolve all undefined references of an input library?
Does
ldd
print only libraries fromDT_NEEDED
structures of.dynamic
section?
No, that is what readelf --dynamic
does.
what is the use of
ldd
at all?
ldd
shows what libraries the runtime linker ld.so
loads when starting your executable or loading a shared library. This is a recursive process, e.g. an executable needs a shared library (DT_NEEDED
), so that library gets loaded. Then it proceeds to load the dependencies of the loaded library (DT_NEEDED
) and so on.
You don't necessarily need ldd
, you can just set LD_DEBUG=all
environment variable to make ld.so
print that information and more. See man ld.so
for more information.
Each loaded executable or shared library expose their defined exported dynamic symbols as a lookup scope (a hash table). Lookup scopes form a list. When resolving an undefined symbol ld.so
walks the lookup scopes and finds the first one that defines the symbol and resolve the symbol reference. If ld.so
reaches the end of lookup scopes it reports the symbol as unresolved.
There is no correspondence between the unresolved symbol name and an executable/shared library it is supposed to come from. ld.so
loads all shared libraries from DT_NEEDED
sections recursively, builds that list of lookup scopes and then looks for unresolved symbols in there.
How To Write Shared Libraries by U. Drepper explains this in full detail.
How to check shared library version in the binary
I use dl_iterate_phdr function to find out which shared objects are loaded. This is example of dl handler that prints shared libs info
static int header_handler(struct dl_phdr_info* info, size_t size, void* data)
{
printf("name=%s (%d segments) address=%p\n",
info->dlpi_name, info->dlpi_phnum, (void*)info->dlpi_addr);
for (int j = 0; j < info->dlpi_phnum; j++) {
printf("\t\t header %2d: address=%10p\n", j,
(void*) (info->dlpi_addr + info->dlpi_phdr[j].p_vaddr));
printf("\t\t\t type=%u, flags=0x%X\n",
info->dlpi_phdr[j].p_type, info->dlpi_phdr[j].p_flags);
}
printf("\n");
return 0;
}
It is taken from here
It prints for my video processing project following :
name=/usr/local/lib/libopencv_highgui.so.2.4 (7 segments) address=0x7f467935a000
name=/usr/local/lib/libopencv_imgproc.so.2.4 (7 segments) address=0x7f46796e9000
...
Opencv includes the version in the name of library libopencv_imgproc.so*.2.4* .
This way i know wich opencv version loaded. I don't know if it is good for your libraries, but it can be a starting point for your.
Related Topics
Difference Between Double and Single Bigger Than in Linux Terminal
Shell Script Not Running via Crontab, Runs Fine Manually
Linux Clipboard Read/Write in C
How to Kill a Whole Process Tree with Perl
Do I Get a Notification from Epoll When a Fd Is Closed
How to Know If I Can Compile with Fma Instruction Sets
How to Make a Cross Compiler Using Gcc
Implementation of Function Execve (Unistd.H)
How to Lock a Directory in C on a Linux Machine
Copying Local Git Config into Docker Container
How to Create a File of Size More Than 2Gb in Linux/Unix
Level Triggered Interrupt Handling and Nested Interrupts
How to Clone a Git Repository Which Is Present on a Remote Linux Server into Windows
Cannot Find Module 'Firebase-Admin' When Trying to Deploy Firebase Functions