Operating system 覆盖内存映射的可执行文件时会发生什么情况?
在我对一个问题的评论之后,我很想知道当一个人重写一个可执行文件时会发生什么。我需要核实我对这件事的理解 假设我有Operating system 覆盖内存映射的可执行文件时会发生什么情况?,operating-system,execution,Operating System,Execution,在我对一个问题的评论之后,我很想知道当一个人重写一个可执行文件时会发生什么。我需要核实我对这件事的理解 假设我有/usr/bin/myprog。我运行它,所以操作系统加载/usr/bin/myprog,可能是通过 无论出于何种原因,该进程仍保留在内存中,我决定实际上我已经修复了一个bug,并覆盖了/usr/bin/myprog 因此,据我所知: 如果已加载myprog的实例,并且我替换了已加载myprog的文件,则myprog的实例不会被修改 如果我运行myprog的新实例,它将使用新代码
/usr/bin/myprog
。我运行它,所以操作系统加载/usr/bin/myprog
,可能是通过
无论出于何种原因,该进程仍保留在内存中,我决定实际上我已经修复了一个bug,并覆盖了/usr/bin/myprog
因此,据我所知:
- 如果已加载
的实例,并且我替换了已加载myprog
的文件,则myprog
的实例不会被修改myprog
- 如果我运行
的新实例,它将使用新代码myprog
myprog
不是100%分页的,这篇维基百科文章暗示将从磁盘上的文件加载新页面,自从加载原始图像以来,该文件发生了变化
但是,我非常确定我的两个编译图像将不相同,并且每个文件的相关地址偏移量也不相同。因此,假设发生这种情况,指令指针将丢失。。。我非常确定操作系统不会将两个不同映像的部分作为同一进程的一部分加载到内存中
那么,对于程序的执行,内存映射/请求分页的组合是如何工作的呢?覆盖该文件是否会在每个可执行文件的页面上触发页面错误,以确保为当前运行的进程加载该文件
我用这个做了一个快速的实验:
#include <stdio.h>
#include <unistd.h>
int main(int argc, char** argv)
{
printf("Program resident...");
while(1)
{
printf("??? Just notifying you I'm still here...\n");
usleep(1000000);
}
return 0;
}
#包括
#包括
int main(int argc,字符**argv)
{
printf(“程序常驻…”);
而(1)
{
printf(“???只是通知您我还在这里…\n”);
美国LEEP(1000000);
}
返回0;
}
果然,我可以a)在这个可执行文件运行时替换它,b)它的输出没有改变
那么到底发生了什么?我特别感谢大家对我能做的事情的建议,看看会发生什么(Linux或Windows)
谢谢大家
编辑:我提到的引发这个问题的问题:
另外,我知道这与编程无关,而是更新可执行文件的结果。然而,我仍然很感兴趣,我想不出比这更好的地方了
rm/usr/bin/myprog
,然后创建一个新的,或者您是否open()
和write()
到现有的/usr/bin/myprog
rm
旧的/usr/bin/myprog
文件,然后创建一个同名的新文件,那么内核/文件系统驱动程序将为新版本提供一个新的inode,并且旧的inode将保留在/proc
文件系统中,直到打开它的进程将其关闭。您现有的进程/usr/bin/myprog
有自己的私有版本的文件,未经修改,直到它close()
s文件描述符mmap()
对于posix,我记不起Windows的等价物-VirtualAlloc()
?)来进行进程加载。这样,可执行文件中任何未被触及的部分都不会加载到内存中mmap()
'd文件,并且两个进程都打开/映射了它,并且在调用mmap()
时都没有指定MAP\u PRIVATE
(即写时复制),那么这两个进程基本上将查看相同的物理内存页,并且如果它们都被称为mmap()
通过PROT_READ
PROT_WRITE
,他们将看到彼此的修改mmap()
'd文件,而进程1已经打开/映射了它,然后进程2开始通过write()
调用(而不是我的mmap
调用)在硬盘上摆弄文件本身,那么进程1确实看到了这些更改。我猜内核会注意到文件正在被修改,并重新加载受影响的页面mmap()
行为?如果我入侵了一个指向某个函数的指针并修改了代码,它会将页面标记为脏页面吗?脏页是否会被写回/usr/bin/myprog
?当我尝试此操作时,它会出现故障,因此我猜,虽然文本页面使用MAP\u SHARED
进行映射,但它们也可能不会得到PROT\u WRITE
,因此在写入时会出现故障_当然,数据段也会被加载到内存中,这些数据段需要修改,但这些数据段可以标记为MAP\u PRIVATE
(写时复制)-因此它们可能不会保持与/usr/bin/myprog
文件的连接write()
级别修改任意mmap()
d文件。当我试图用write()
在另一个进程中修改可执行文件(即mmap()
'd)时,我不会得到与第5点相同的结果。我可以通过裸write()
调用对可执行文件进行各种可怕的更改,但什么也没有发生。然后,当我退出进程并尝试再次运行它时,它崩溃了(当然,在我对可执行文件做了所有操作之后)。这使我困惑。我无法将参数排列到mmap()
以使其