The dynamic linker actually searches several places to find each dynamic library. These include (from man ld.so):
- Paths given by the environment variable
LD_LIBRARY_PATH
- Paths baked into the binary load the library under the
DT_RUNPATH
entry
- The cache file /etc/ld.so.cache
- /lib and /usr/lib
If you want to get the path for a specific shared library, I would recommend the dladdr
function. From the man page:
The function dladdr() takes a function pointer and tries to resolve
name and file where it is located. Information is stored in the
Dl_info
structure:
typedef struct {
const char *dli_fname; /* Pathname of shared object that
contains address */
void *dli_fbase; /* Address at which shared object
is loaded */
const char *dli_sname; /* Name of nearest symbol with address
lower than addr */
void *dli_saddr; /* Exact address of symbol named
in dli_sname */
} Dl_info;
If no symbol matching addr could be found, then dli_sname
and
dli_saddr
are set to NULL
.
dladdr()
returns 0 on error, and non-zero on success.
So you just give it a function pointer, and it will give you the name of the file which supplies it and a bunch of other information. So for instance, you could have a constructor in a library call this on itself to find out the full path of the library:
#define _GNU_SOURCE
#include <dlfcn.h>
#include <stdio.h>
__attribute__((constructor))
void on_load(void) {
Dl_info dl_info;
dladdr((void *)on_load, &dl_info);
fprintf(stderr, "module %s loaded
", dl_info.dli_fname);
}
This function also works on OS X with the same semantics.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…