【问题标题】:How can a C shared library function learn the executable's pathC 共享库函数如何学习可执行文件的路径
【发布时间】:2014-04-17 02:30:01
【问题描述】:

我正在 Linux 中编写一个 C 共享库,其中一个函数想要发现当前运行的可执行文件的路径。它无法访问 main() 中的 argv[0],我不想要求访问库的程序将其传入。

这样的函数如何在 main() 之外和在野外找到正在运行的可执行文件的路径?到目前为止,我想到了 2 种相当不可移植、不可靠的方法:1) 尝试读取 /proc/getpid()/exe 和 2) 尝试将堆栈爬升到 __libc_start_main() 并读取堆栈参数。我担心所有安装了 /proc 的机器。

你能想出别的办法吗?在 dlopen(NULL, 0) 的任何地方都埋有什么东西吗?我可以从内核中获得可靠的 self proc 映像吗??

感谢您的任何想法。

【问题讨论】:

  • 很可能 argv[0] 无论如何都不是一种可靠的方法,因为那里给出的名称可能与当前工作目录在进程开始时相关
  • 请注意,并非所有非 Linux 系统都有/proc(例如 Mac OS X 没有它),并且那些不一定具有与 Linux 相同的结构(例如 Solaris,在至少在旧版本中)。

标签: c executable filepath


【解决方案1】:

/proc 是您最好的机会,因为“可执行文件的路径”在 Linux 中并不是一个定义明确的概念(您甚至可以在程序运行时将其删除)。

要获得已加载模块的分解(主可执行文件通常是第一个条目),您应该查看/proc/<pid>/maps。这是一个文本格式的文件,它允许您将可执行文件和库路径与加载地址相关联(如果前者已知并且仍然有效)。

【讨论】:

    【解决方案2】:

    除非您编写的软件可能在系统启动的早期非常使用,否则您可以放心地假设/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),而不是其绝对路径。

    【讨论】:

      猜你喜欢
      • 2012-09-16
      • 1970-01-01
      • 2010-12-19
      • 2022-11-10
      • 1970-01-01
      • 2018-10-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多