【问题标题】:POSIX: How do you determine your own process's file image so you can exec yourself? [duplicate]POSIX:您如何确定自己的进程的文件映像,以便自己执行? [复制]
【发布时间】:2013-11-14 05:15:05
【问题描述】:

如何确定代表当前进程可执行文件的文件?

问题是argv[0]不可靠,就像是通过execXp调用的一样,满足非限定命令的路径条目可能会也可能不会被前置。此外,exec* 的任何调用者都可以将 argv[0] 替换为 ANYTHING。

因此,如果您运行ps,则不能保证argv[0] 将是"/usr/bin/ps"。事实上,您可能会得到 OPOSITE 的保证。

我需要以下物品之一:

  1. 完整路径名(不用自己搜索路径,以免我使用的envp不是shell使用的那个)
  2. 与当前进程映像对应的文件的实时、预先打开的文件描述符
  3. 一些与当前内存中的代码段相对应的魔法描述符(虽然不太确定 BSS 段)

通过这种方式,在启动时我可以快速打开一个 FD 到我自己的可执行文件(对于案例 1.,以防文件被删除并变得无法打开),然后在更晚的日期调用:

int fexecve(int fd, char *const argv[], char *const envp[]);

fork/exec 我自己(通常需要在 OS-X 上解决fork() 之后的全局和系统描述符状态的不可靠性)。换句话说(这个例子当然很傻):

void magicallyReplicate(argc, argv)
{
  if (!fork()) {
    magicallyExecMyself(argc, argv);
  }
}

甚至只是:

void startOver(argc, argv)
{
  magicallyExecMyself(argc, argv);
}

当然,在我的示例中,我将使用不同的argv,以便我可以在不同的模式下运行。

(早期的“不”反驳:你不能使用clone(),因为它是fork()的血统)

【问题讨论】:

  • How does one determine the file that represents the current process' executable?。 pmap 如何确定代表进程的文件对您来说可以吗?作为一个例子,它开始它的输出,例如对于 bash 进程:0000000000400000 848K r-x-- /bin/bash
  • 任何能让我找到路径或打开 FD 的方式都可以。我什至不相信当前的搜索点对 fexecve 很重要。
  • 那你为什么不直接阅读 /proc/PID/maps 呢?它在第一行包含正在运行的进程的文件名。
  • /proc/pid 不符合 POSIX...否则,我会的。好主意,但在 LINUX 上会很棒!
  • 顺便说一下你的问题有标签linux

标签: c linux exec posix fork


【解决方案1】:

所以基本上,最简单的平台是 MacOS(因为 libc 完全损坏,如果在 forkexec 之间调用 getaddrinfo segfault 等简单的东西) - 在 Darwin 上,内核将你交给一个盘子启动进程时的完整二进制名称。使用 main (http://web.archive.org/web/20170816030258/http://unixjunkie.blogspot.com/2006/02/char-apple-argument-vector.html) 的第四个参数或完全相同的 _NSGetExecutablePath 检索它 - 它只是一个知道内核放置文件名的相同特殊位置的函数。

对于所有平台,这是一个个案问题。此线程中的完整详细信息:Finding current executable's path without /proc/self/exe

【讨论】:

  • 天哪,伙计,你是个英雄!谢谢!顺便说一句,Darwin 和 MacOS 是我的第一个平台,所以 doubleplusgood。
猜你喜欢
  • 1970-01-01
  • 2010-12-09
  • 1970-01-01
  • 1970-01-01
  • 2014-01-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多