共享库如何知道它所在的位置?
How can a shared library know where it resides?
我正在为 linux 机器开发一个共享库,它是相对于使用 rpath 的主要可执行文件动态加载的。
现在,库本身尝试相对于其位置动态加载其他库,但没有 rpath(我使用 scandir 在某个文件夹中搜索共享库——我还不知道它们的名字)。
这仅在工作目录设置为共享库位置时有效,否则我会按预期查看不同的目录。
共享库是否有任何实用、可靠的方法来确定它所在的位置?
我知道,我可以使用 /proc/self/maps 或类似的东西来获取加载的文件,但这只有效,只要库知道它自己的名字。
另一个想法是使用 dlinfo(),但是要使用它,共享库需要知道它自己的句柄。
Is there any practical, reliable way for the shared library
to determine where it resides?
我会使用 dlinfo
和 /proc/self/maps
(proc
可能并不总是被挂载,尤其是在容器中)。
I know, I could use /proc/self/maps or something like that,
to get the loaded files, but this works only, as long the library
knows its own name.
不一定,您可以获取一个指向库内某些代码的指针(最好是指向某些内部标签,以避免与 PLT/GOT 混淆)并将结果与从 /proc/self/maps
获得的内存范围进行比较(或dlinfo
).
无需处理页面映射或 dlinfo
。您可以在共享库中定义的任何符号上使用 dladdr
:
#define _GNU_SOURCE
#include <dlfcn.h>
#include <stdlib.h>
static char *lib_path(void) {
Dl_info info;
if (! dladdr((void *) lib_path, & info)) return NULL;
return realpath(info.dli_fname, NULL);
}
从技术上讲,这不可移植;实际上,它甚至可以在 on-Linux 系统(例如 macOS)上运行。您可能需要手动为 realpath
分配存储空间以避免出现非标准行为(在 Linux 和 macOS 上,realpath
本身就是 malloc
的存储空间,并且需要free
d 由来电者提供)。
此 returns 路径 共享库本身 。如果要获取目录,可以使用dirname
之类的(注意:可重入)或者自己修改字符串。
我正在为 linux 机器开发一个共享库,它是相对于使用 rpath 的主要可执行文件动态加载的。 现在,库本身尝试相对于其位置动态加载其他库,但没有 rpath(我使用 scandir 在某个文件夹中搜索共享库——我还不知道它们的名字)。
这仅在工作目录设置为共享库位置时有效,否则我会按预期查看不同的目录。
共享库是否有任何实用、可靠的方法来确定它所在的位置?
我知道,我可以使用 /proc/self/maps 或类似的东西来获取加载的文件,但这只有效,只要库知道它自己的名字。
另一个想法是使用 dlinfo(),但是要使用它,共享库需要知道它自己的句柄。
Is there any practical, reliable way for the shared library to determine where it resides?
我会使用 dlinfo
和 /proc/self/maps
(proc
可能并不总是被挂载,尤其是在容器中)。
I know, I could use /proc/self/maps or something like that, to get the loaded files, but this works only, as long the library knows its own name.
不一定,您可以获取一个指向库内某些代码的指针(最好是指向某些内部标签,以避免与 PLT/GOT 混淆)并将结果与从 /proc/self/maps
获得的内存范围进行比较(或dlinfo
).
无需处理页面映射或 dlinfo
。您可以在共享库中定义的任何符号上使用 dladdr
:
#define _GNU_SOURCE
#include <dlfcn.h>
#include <stdlib.h>
static char *lib_path(void) {
Dl_info info;
if (! dladdr((void *) lib_path, & info)) return NULL;
return realpath(info.dli_fname, NULL);
}
从技术上讲,这不可移植;实际上,它甚至可以在 on-Linux 系统(例如 macOS)上运行。您可能需要手动为 realpath
分配存储空间以避免出现非标准行为(在 Linux 和 macOS 上,realpath
本身就是 malloc
的存储空间,并且需要free
d 由来电者提供)。
此 returns 路径 共享库本身 。如果要获取目录,可以使用dirname
之类的(注意:可重入)或者自己修改字符串。