如何使用 dlopen() 获取可执行文件路径

How to use dlopen() to get the executables path

我正在尝试使用 dlopen() 和 dlinfo() 来获取我的可执行文件的路径。我可以通过使用 dlopen() 返回的句柄获得 .so 的路径,但是当我使用 dlopen(NULL,RTLD_LAZY); 返回的句柄时那么我返回的路径是空的。

void* executable_handle = dlopen(0, RTLD_LAZY);
if (nullptr != executable_handle) 
{
    char pp_linkmap[sizeof(link_map)];
    int r = dlinfo(executable_handle, RTLD_DI_LINKMAP, pp_linkmap);
    if (0 == r)
    {
        link_map* plink = *(link_map**)pp_linkmap;
        printf("path: %s\n", plink->l_name);
    }
}

我认为可执行文件的句柄可以像使用 .so 句柄一样在 dlinfo 函数中使用的假设是错误的吗?

Am I wrong in my assumption that the handle for the executable can be used in the dlinfo functions the same way a .so handle can be used?

是的,你是。

动态链接器不知道主要可执行文件是从哪个文件加载的。那是因为 kernel 执行主可执行文件的所有 mmaps,并且只将文件描述符传递给动态加载器(谁的工作是加载其他所需的库并为可执行 运行ning).

I'm trying to replicate some of the functionality of GetModuleFileName() on linux

没有可靠的方法来做到这一点。事实上,可执行文件可能不再 存在 磁盘上的任何地方——完全可以 运行 可执行文件并在程序仍然存在时删除可执行文件 运行宁.

硬链接也意味着可能有多个正确答案——如果 a.outb.out 是硬链接,则没有简单的方法来判断 a.outb.out 用于启动程序 运行ning.

您最好的选择可能是阅读 /proc/self/exe,或解析 /proc/self/cmdline and/or /proc/self/maps.

BSD 实用程序库有一个函数 getprogname(3) 可以完全满足您的需求。在这种情况下,我建议它比 procfs 更便携、更易于使用。