我正在Linux中编写一个C共享库,其中一个函数想要发现当前运行的可执行文件的路径。它无法访问main()中的argv [0],我也不想要求访问该库的程序将其传入。
这样的函数(在main()之外和野外)如何才能到达正在运行的可执行文件的路径?到目前为止,我已经想到了两种相当不可移植,不可靠的方法:1)尝试读取/ proc / getpid()/ exe和2)尝试将堆栈爬到__libc_start_main()并读取堆栈参数。我担心所有装有/ proc的机器。
你能想到另一种方式吗?在dlopen(NULL,0)中是否有埋藏的东西?我可以从内核获得可靠的自我proc图像吗?
感谢您的任何想法。
答案 0 :(得分:1)
/proc
是你最好的机会,因为“可执行文件的路径”不是Linux中那个定义明确的概念(你甚至可以在程序运行时删除它)。
要获取已加载模块的细分(主要可执行文件通常是第一个条目),您应该查看/proc/<pid>/maps
。它是一个文本格式的文件,允许您将可执行文件和库路径与加载地址相关联(如果前者已知且仍然有效)。
答案 1 :(得分:1)
除非您正在编写可在系统启动早期使用非常的软件,否则您可以放心地假设/proc
将始终安装在Linux系统上。它包含许多不能以任何其他方式访问的数据,因此必须安装才能使系统正常运行。因此,您可以使用以下方法轻松获取可执行文件的路径:
readlink("/proc/self/exe", buf, sizeof(buf));
如果由于某种原因你想避免这种情况,也可以从流程auxiliary vector中读取它:
#include <sys/auxv.h>
#include <elf.h>
const char *execpath = (const char *) getauxval(AT_EXECFN);
请注意,这将需要最新版本的glibc(2.16或更高版本)。它还会返回用于执行应用程序的路径(例如,可能类似./binary
),而不是其绝对路径。