程序执行步骤

Program execution steps

本文关键字:执行 程序      更新时间:2023-10-16

我有一个运行良好的c++程序,但它需要运行很长时间。但是当它运行时,我可以继续开发它的某些部分。如果我重新编译我的程序,这将用新的二进制文件替换二进制文件。这会修改正在运行的程序的行为吗?还是程序启动后,进程和二进制文件是两个独立的东西?

更一般地说,程序执行的步骤是什么?

在Linux上,进程使用内存映射将可执行文件的文本部分和共享库直接映射到正在运行的进程内存中。因此,如果您可以覆盖可执行文件,它将影响运行过程。但是,禁止向映射为执行的文件中写入内容——会出现"文本文件繁忙"错误。

但是,您仍然可以重新编译程序。如果编译器(实际上是链接器)收到这个错误,它会删除旧的可执行文件并创建一个新的文件。在Unix上,如果删除正在使用的文件,文件内容实际上不会从磁盘中删除,只会删除目录项中的引用;直到所有对该文件的引用(目录条目、文件描述符和内存映射)都消失,该文件才会被完全删除。因此,正在运行的进程将继续映射到旧的无名称文件。您可以通过以下演示看到这一点:

barmar@dev:~$ ls -li testsleep
229774 -rwxr-xr-x 1 barmar adm 4584 Apr 24 04:30 testsleep
barmar@dev:~$ ./testsleep &
[1] 17538
barmar@dev:~$ touch testsleep.c
barmar@dev:~$ make testsleep
cc     testsleep.c   -o testsleep
barmar@dev:~$ ls -li testsleep
229779 -rwxr-xr-x 1 barmar adm 4584 Apr 24 04:32 testsleep

当程序运行时重新编译时,inode编号从229774变为229779,这表明创建了一个新文件。

在Windows上,当旧版本运行时,您甚至无法编写新的可执行文件。进程存在时,磁盘上的文件被锁定。在Linux上,您可以覆盖磁盘上的文件,但内存中的副本保持不变。

OTOH,当在IDE中运行时,可能会对运行过程进行修补,因为IDE知道相关的细节。但它很复杂,并不是所有IDE都支持这一点。