Joerg Schilling wrote: > Is there a way to reliably retrieve the path to a library? > > I tried to opendir("/proc/<pid>/path/") > and readdir()/readlink() the entries. If all library > names differ, this allows to find the path to any lib of > interest. > > Unfortunately, this does not help if there are two > libraries with the same name (e.g. /tmp/libm.so.2 > and /lib/libm.so.2). Is there a way to get the > path that is related to a handle returned by dlopen()?
You can use dlinfo() to get the origin of the dlopen() caller, together with the pathnames that were opened: chaz 1861. pwd /home/rie/joerg chaz 1862. mkdir one two chaz 1863. cat null.c void null(){} chaz 1864. cc -G -o one/null.so.1 -Kpic null.c chaz 1865. cc -G -o two/null.so.1 -Kpic null.c chaz 1866. cat main.c #include <dlfcn.h> #include <link.h> #include <stdio.h> #include <limits.h> void main() { void *handle; Link_map *lmp; char origin[PATH_MAX]; (void) dlinfo(RTLD_SELF, RTLD_DI_ORIGIN, origin); (void) printf("origin: %s\n", origin); handle = dlopen("one/null.so.1", RTLD_LAZY); (void) dlinfo(handle, RTLD_DI_LINKMAP, &lmp); (void) printf("name: %s/%s\n", origin, lmp->l_name); handle = dlopen("two/null.so.1", RTLD_LAZY); (void) dlinfo(handle, RTLD_DI_LINKMAP, &lmp); (void) printf("name: %s/%s\n", origin, lmp->l_name); } chaz 1883. cc -o main main.c chaz 1884. ./main origin: /home/rie/joerg name: /home/rie/joerg/one/null.so.1 name: /home/rie/joerg/two/null.so.1 Or, you could retrieve a known symbol from the handle, and get the associated address information from dladdr(): chaz 1902. cat main.c #include <dlfcn.h> #include <stdio.h> void main() { void *handle; void *fptr; Dl_info dli; handle = dlopen("one/null.so.1", RTLD_LAZY | RTLD_FIRST); fptr = (void *)dlsym(handle, "null"); (void) dladdr(fptr, &dli); (void) printf("name: %s\n", dli.dli_fname); handle = dlopen("two/null.so.1", RTLD_LAZY | RTLD_FIRST); fptr = (void *)dlsym(handle, "null"); (void) dladdr(fptr, &dli); (void) printf("name: %s\n", dli.dli_fname); } chaz 1903. cc -o main main.c chaz 1904. ./main name: /home/rie/joerg/one/null.so.1 name: /home/rie/joerg/two/null.so.1 -- Rod.