4

假设一个二进制可执行程序正在运行:

例如:ps -eaf | grep someServer

表明 someServer 正在运行。

是否可以判断磁盘上的 someServer 可执行文件(例如 /usr/bin/someServer)是否与实际启动的程序匹配?

4

3 回答 3

8

是:使用软链接/proc/$pid/exe获取用于加载代码的路径。

调查/proc/$pid/maps。它看起来像这样(对于/sbin/getty):

00400000-00407000 r-xp 00000000 08:01 3145779                            /sbin/getty
00606000-00607000 r--p 00006000 08:01 3145779                            /sbin/getty
00607000-00608000 rw-p 00007000 08:01 3145779                            /sbin/getty
... lots more ...

使用您从软链接获得的路径过滤文件,以找到您感兴趣的行。

最后一个数字 ( 3145779) 是文件的 inode。当您在磁盘上创建一个新文件时,它会获得一个新的 inode。

要查看文件的 inode,请使用ls --inode /sbin/getty

3145779 /sbin/getty

由于这两个数字仍然相同,因此磁盘上的可执行文件与 RAM 中的可执行文件相同。

背景:Linux 不会立即将进程加载到 RAM 中。相反,可执行文件使用虚拟内存子系统将内存映射到 RAM。这意味着您从不使用的可执行文件部分将永远不会加载到内存中。这也意味着内核使用磁盘上的可执行文件作为“缓存”。

当您覆盖磁盘上的可执行文件时,原始 inode 不会更改。您现有的流程会继续使用它。相反,会创建一个新的 inode 并更新目录节点(包含文件名和指向带有数据的 inode 的指针)。这就是您可以覆盖当前在 Linux 上使用的文件的原因。

当使用它的最后一个进程死亡时,原始 inode 将被清理。

于 2013-07-11T13:20:11.190 回答
1

我不确定你到底是什么意思。

  • 使用 pid 匹配(比较服务器中的 ps 输出和 getpid())
  • 使用 /proc/$pid/environ 并找到 _=path_to_someServer (有二进制文件)
  • 使用diff /proc/$pid/exe someServer ("type someServer" 获取完整路径)
于 2013-07-11T12:08:44.627 回答
0

如果您想知道是否有任何正在运行的进程是从特定的可执行 inode 产生的:

# find -L /proc/[0-9]*/exe -samefile /usr/bin/someServer

此命令将输出一个/proc/<pid>/exe路径名列表,每个进程的可执行映像从与当前链接的相同 inode 映射到内存中/usr/bin/someServer

请注意,该命令不会找到从以前链接的inode 生成的进程,/usr/bin/someServer但后来取消链接,例如,如果可执行文件的较新版本替换了正在运行的版本。

于 2020-09-23T03:36:26.547 回答