可执行目标文件和虚拟内存

2023-12-13

我是 Linux 和虚拟内存的初学者,仍在努力理解虚拟内存和可执行对象文件之间的关系。

假设我们有一个可执行目标文件a.out存储在硬盘驱动器磁盘上,假设最初 a.out 有一个.data具有值为 2018 的全局变量的部分。 当加载程序运行时,它会分配一个连续的虚拟页面块,将它们标记为无效(即未缓存)并将其页表条目指向 a.out 中的适当位置。加载器实际上从未将任何数据从磁盘复制到内存中。第一次引用每个页面时,虚拟内存系统会根据需要自动对数据进行分页。

我的问题是:假设程序在运行时将全局变量的值从 2018 年更改为 2019 年,并且似乎包含全局变量的虚拟页最终将分页到磁盘,这意味着.data部分现在的全局变量为2019,所以我们更改了哪些不应该更改的可执行目标文件?否则每次完成并再次运行程序时我们都会得到不同的值?


一般来说(不是专门针对 Linux)...

当可执行文件启动时,操作系统(内核)创建虚拟地址空间和(最初为空)进程,并检查可执行文件的标头。可执行文件的标头描述了“部分”(例如.text, .rodata, .data, .bss等)其中每个节都有不同的属性 - 节的内容是否应该放入虚拟地址空间(例如是符号表或运行时不使用的东西),如果内容是部分是否包含文件(例如.bss),以及该区域是否可执行、只读或读/写。

通常,可执行文件(的已使用部分)由虚拟文件系统缓存;并且已经存在于 VFS 缓存中的文件片段可以被映射(作为“写时复制”)到新进程的虚拟地址空间。对于尚未在 VFS 缓存中的部分,可以将文件的这些部分映射为“需要获取”到新进程的虚拟地址空间。

然后进程启动(给定 CPU 时间)。

如果进程从尚未加载的页面读取数据;操作系统(内核)暂停进程,从磁盘上的文件中提取页面到 VFS 缓存中,然后将该页面作为“写时复制”映射到进程中;然后允许进程继续(允许进程重试从未加载的页面读取,这将在页面加载后起作用)。

如果进程写入的页面仍然是“写时复制”;操作系统(内核)暂停进程,分配一个新页面并将原始页面的数据复制到其中,然后用进程自己的副本替换原始页面;然后允许进程继续(允许进程重试写入,现在该进程拥有自己的副本,该写入将起作用)。

如果进程从尚未加载的页面写入数据;操作系统(内核)结合了前面的两件事(从磁盘获取原始页面到VFS缓存,创建一个副本,将进程的副本映射到进程的虚拟地址空间)。

如果操作系统开始耗尽可用 RAM;然后:

  • 位于 VFS 缓存中但未与任何进程作为“写入时复制”共享的文件数据页可以在 VFS 中释放,无需执行任何其他操作。下次使用该文件时,这些页面将从磁盘上的文件中提取到 VFS 缓存中。

  • VFS 缓存中的文件数据页以及与任何进程共享为“写入时复制”的文件数据页可以在 VFS 中释放,并且任何/所有进程中的副本标记为“尚未获取”。下次使用该文件时(包括进程访问“尚未获取”页面时),这些页面将从磁盘上的文件获取到 VFS 缓存,然后在进程中映射为“写时复制” )。

  • 已修改的数据页(或者因为它们最初是“写时复制”但被复制,或者因为它们根本不是可执行文件的一部分 - 例如.bss节、可执行文件的堆空间等)可以保存到交换空间,然后释放。当进程再次访问页面时,将从交换空间中获取它们。

注意:如果可执行文件存储在不可靠的介质上(例如可能有划痕的 CD),“比平均水平更智能”的操作系统可能会首先将整个可执行文件加载到 VFS 缓存和/或交换空间中;因为当进程使用该文件时,除了使进程崩溃之外,没有明智的方法来处理“从内存映射文件读取错误”(例如SIGSEGV)并使其看起来像是可执行文件有错误,而实际上并没有,因为这提高了可靠性(因为您依赖于更可靠的交换,而不是依赖于不太可靠的有划痕的 CD)。还;如果操作系统防止文件损坏或恶意软件(例如,可执行文件中内置了 CRC 或数字签名),则操作系统可能(应该)将所有内容加载到内存(VFS 缓存)中,以在允许可执行文件被执行之前检查 CRC 或数字签名。执行,并且(对于安全系统,如果在可执行文件运行时修改了磁盘上的文件)释放 RAM 时可能会将未修改的页面存储在“更可信”的交换空间中(与修改页面时的情况相同)以避免从原始的“不太受信任”的文件中获取数据(部分原因是您不想每次从文件加载页面时都进行整个数字签名检查)。

我的问题是:假设程序在运行时将全局变量的值从 2018 年更改为 2019 年,并且似乎包含全局变量的虚拟页最终将分页到磁盘,这意味着 .data 部分具有全局变量现在变量为2019,所以我们更改了哪些不应该更改的可执行目标文件?

该页面包含2018将以“未获取”开始,然后(当访问时)加载到 VFS 缓存中并作为“写时复制”映射到进程。在任一时刻,操作系统都可以释放内存并从磁盘上的可执行文件中获取数据(未更改)(如果再次需要)。

当进程修改全局变量(将其更改为包含2019)操作系统为进程创建它的副本。此后,如果操作系统想要释放内存,则操作系统需要将页面的数据保存在交换空间中,并在再次访问时从交换空间加载页面的数据。可执行文件不会被修改,并且(对于该页面,对于该进程)不会再次使用可执行文件。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

可执行目标文件和虚拟内存 的相关文章

  • 使用 gcc 理解共享库

    我试图理解 C 中共享库的以下行为 机器一 cat one c include
  • 在 Linux 上创建线程与进程的开销

    我试图回答在 python 中创建线程与进程有多少开销的问题 我修改了类似问题的代码 该问题基本上运行一个带有两个线程的函数 然后运行带有两个进程的相同函数并报告时间 import time sys NUM RANGE 100000000
  • 无需 root 访问权限即可安装 zsh? [关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 有可能 以及如何 我确实需要在几台具有 ssh 访问权限 但没有 root 访问权限 的远程计算机上使用此功能 下载 zsh wget O zsh t
  • 如何重命名 .tar.gz 文件而不提取内容并在 UBUNTU 中创建新的 .tar.gz 文件?

    我有一个命令将创建一个新的 tar gz现有文件中的文件 sudo tar zcvf Existing tar gz New tar gz 该命令将创建一个新的New tar gz从现有的文件Existing tar gz file 谁能告
  • 裸机交叉编译器输入

    裸机交叉编译器的输入限制是什么 比如它不编译带有指针或 malloc 的程序 或者任何需要比底层硬件更多的东西 以及如何才能找到这些限制 我还想问 我为目标 mips 构建了一个交叉编译器 我需要使用这个交叉编译器创建一个 mips 可执行
  • 如何反汇编、修改然后重新组装 Linux 可执行文件?

    无论如何 这可以做到吗 我使用过 objdump 但它不会产生我所知道的任何汇编器都可以接受的汇编输出 我希望能够更改可执行文件中的指令 然后对其进行测试 我认为没有任何可靠的方法可以做到这一点 机器代码格式非常复杂 比汇编文件还要复杂 实
  • 如何列出 nginx 中的所有虚拟主机

    有没有一个命令可以列出 CentOS 上 nginx 下运行的所有虚拟主机或服务器 我想将结果通过管道传输到文本文件以用于报告目的 我正在寻找与我用于 Apache 的命令类似的命令 apachectl S 2 gt 1 grep 端口 8
  • 如何在文件夹中的 xml 文件中 grep 一个单词

    我知道我可以使用 grep 在这样的文件夹中的所有文件中查找单词 grep rn core 但我当前的目录有很多子目录 我只想搜索当前目录及其所有子目录中存在的所有 xml 文件 我怎样才能做到这一点 我试过这个 grep rn core
  • 比较linux中的两个未排序列表,列出第二个文件中的唯一项

    我有 2 个包含号码列表 电话号码 的文件 我正在寻找一种列出第二个文件中第一个文件中不存在的数字的方法 我尝试过各种方法 comm getting some weird sorting errors fgrep v x f second
  • 运行 shell 命令并将输出发送到文件?

    我需要能够通过 php 脚本修改我的 openvpn 身份验证文件 我已将我的 http 用户设置为免通 sudoer 因为这台机器仅在我的家庭网络中可用 我目前有以下命令 echo shell exec sudo echo usernam
  • Grep 递归和计数

    需要在具有大量子目录的目录中搜索文件内的字符串 我在用着 grep c r string here 我怎样才能找到总数量 如何仅输出至少具有一个实例的文件 使用 Bash 的进程替换 这给出了我认为是您想要的输出 如果不是 请澄清问题 gr
  • 为什么 call_usermodehelper 大多数时候都会失败?

    从内核模块中 我尝试使用 call usermodehelper 函数来执行可执行文件 sha1 该可执行文件将文件作为参数并将文件的 SHA1 哈希和写入另一个文件 名为输出 可执行文件完美运行 int result 1 name hom
  • 亚马逊 Linux - 安装 openjdk-debuginfo?

    我试图使用jstack在 ec2 实例上amazon linux 所以我安装了openjdk devel包裹 sudo yum install java 1 7 0 openjdk devel x86 64 但是 jstack 引发了异常j
  • 查找并删除超过 x 天的文件或文件夹

    我想删除超过 7 天的文件和文件夹 所以我尝试了 17 07 14 email protected cdn cgi l email protection find tmp mindepth 1 maxdepth 1 ctime 7 exec
  • 使用 --prof 选项创建多个日志文件而不是一个 v8.log 的节点

    我正在尝试使用 prof 选项来分析我的 Node 应用程序 但我发现不是一个单一的 v8 log 文件 而是使用诸如isolate 0x9582b40 v8 log isolate 0xa1cab78 v8 6049 等前缀创建的多个文件
  • 操作系统中的用户模式和内核模式有什么区别?

    用户模式和内核模式之间有什么区别 为什么以及如何激活它们 以及它们的用例是什么 内核模式 在内核模式下 执行代码具有完整且不受限制的 访问底层硬件 它 可以执行任何CPU指令并且 引用任意内存地址 核心 模式通常保留给 最低级别 最受信任的
  • Linux下单个目录下文件过多会怎样?

    如果一个目录中有大约 1 000 000 个单独的文件 大部分大小为 100k 其中没有其他目录和文件 是否会以任何其他可能的方式降低效率或产生缺点 ARG MAX 会对此提出异议 例如 rm rf 在目录中时 会说 参数太多 想要执行某种
  • 为什么使用signalfd无法捕获SIGSEGV?

    我的系统是ubuntu 12 04 我将示例修改为man 2 signalfd 并添加sigaddset mask SIGSEGV 在示例中 但我无法得到输出SIGSEGV被生成 这是一个错误吗glibc 源代码片段如下 sigemptys
  • 命名互斥体的 Mono 替代方案

    在 Windows NET 上 命名的互斥体可用于同步多个进程 不幸的是 Mono 在 Linux 上不太支持这一点 他们的发行说明 http www mono project com Release Notes Mono 2 8 Shar
  • 如何查看共享库加载的顺序

    给定一个 ELF 二进制文件或共享对象 我如何才能最轻松地查看所需共享库的加载顺序 它们是否按照列出的顺序加载readelf d 我怎样才能最容易地看到所需共享库的加载顺序 Use LD DEBUG LD DEBUG files bin l

随机推荐

  • 为什么加载 fxml 时会出现 stackoverflow?

    我已经调整了控制器构造函数和 fxml 以便除了 FXML 构造和 fxml 加载之外 fxml 到控制器的所有设置都在 fxml 中 这是我的控制器 public class MainOverviewTab extends Tab FXM
  • 在 JavaScript/Jquery 中获取 DD-Mon-YYYY 格式的当前日期

    我需要在 JavaScript 中获取日期格式为 DD Mon YYYY 我曾问过一个question 并且它被标记为重复jQuery 日期格式 但是 问题中提供的答案是以 DD MM YYYY 格式获取当前日期 而不是 DD MON YY
  • ubuntu中wordpress自动更新的apache和sftp权限[关闭]

    Closed 这个问题是无关 目前不接受答案 这是我第一次尝试在云托管上设置 Wordpress 或任何网站 我在 Ubuntu 服务器上 Wordpress 位于 var www mydomain public 文件夹中 我想要实现的是
  • Excel 2007 中数值的可视化与底层 xml 文件不一致

    我试图从 Excel 外部读取 Excel 2007 文件 xlsx 但发现了无法解释的不一致之处 如果您在单元格中输入值 19 99 然后查看基础 Xml 文档 它实际上存储为 19 989999999999998 这不是执行此操作的唯一
  • Log4j 滚动策略和 MaxbackupIndex

    我使用下面的代码每分钟滚动日志 它工作得很好 log4j appender AllFlows org apache log4j rolling RollingFileAppender log4j appender AllFlows roll
  • 如何使用 Bison 解析 C 字符串

    Closed 这个问题需要细节或清晰度 目前不接受答案 我的 C 文件中有一个字符串 如下所示 char test print x 我想用我编写的 Bison 解析器来解析它 是否可以 Bison 解析器根本不读取输入 他们只是通过重复调用
  • 如何迭代priority_queue?

    我可以遍历一个标准吗priority queue或标准queue在 C 中带有迭代器 比如vector 我不想使用 pop 因为它会导致我的队列出队 谢谢你的帮助 priority queue不允许迭代所有成员 大概是因为很容易使队列的优先
  • 如何通过 _blank 在新窗口中打开链接并在后台打开?

    对于正常链接 a href xxx target blank 链接将在新窗口 或选项卡 中打开 我想知道是否有办法在后台打开它 并保持当前窗口仍然处于活动状态 您先请open新窗口 我们称之为newWindow 做这个 newWindow
  • 如何从{$$state:Object}获取数据?

    我尝试使用工厂从数据库中获取数据 我有一个问题 因为我不知道如何从工厂返回的对象中获取数据 这是我使用 console log 函数时收到的信息 gt d state Object state Object status 1 value A
  • 获取并非每天发生的事件的每日计数

    我有一个customer当客户注册时会在其中插入新行的表 Problem 我想知道给定日期范围内每天的注册总数 例如 查找2015 07 01到2015 07 10每天的注册总数 顾客表样本数据 显示相关列 customerid usern
  • amazon-s3 中的 Errno::ENOENT (没有此类文件或目录)

    我有使用 amazon s3 将图像发布到存储桶部署到 heroku 的应用程序 这工作得很好 但是当获取相同的图像时会出现错误 Errno ENOENT No such file or directory showing path s3
  • 为 CUDA 内核调用设置 Visual Studio Intellisense

    我刚刚开始 CUDA 编程 进展非常顺利 我的 GPU 被识别了等等 我已经使用这里非常有用的指南在 Visual Studio 中部分设置了 Intellisense http www ademiller com blogs tech 2
  • 如何将 C++ 中的 QStringList 显示到 QML ListView

    所以我是 Qt 的新手 我正在努力提高我的 C 技能 所以我决定启动一个项目 在其中我可以使用文本字段搜索 QStringList 中的项目 我使搜索功能正常工作 并且能够将搜索结果移至另一个QStringList 我可以使用它在声明为 公
  • 我如何覆盖核心 Symfony2 类?

    我想重写核心 Symfony2 类 具体来说 我想覆盖供应商 symfony symfony src Symfony Bundle FrameworkBundle Template TemplateReference php Templat
  • 如何在Boost Spirit解析器中打印符号表匹配的变量?

    我是使用初学者boost spirit 假设我有以下代码来解析带有变量的简单算术表达式 include
  • 使用 sed 插入换行符 (\n)

    我正在尝试将一些列表清理到格式正确的 CSV 文件中以进行数据库导入 我的起始文件看起来像这样 每个 行 应该跨越多行 如下所示 Mr John Doe Exclusively Stuff 186 Caravelle Drive Ponte
  • context.filter 在 safari 上不起作用

    我正在使用 React 和 Safari 构建一个绘图应用程序 context filter无法正常工作 下面是在 chrome 和 firefox 上渲染的图片以及在 safari 上渲染的图片 对于 Safari 来说还有其他选择吗 S
  • 使用PCA选择特征

    我正在做无监督分类 为此 我有 8 个特征 绿色方差 绿色标准差 红色平均值 红色方差 红色标准差 色调平均值 色调方差 色调标准差 用于分类每个图像 我想使用 PCA 选择 3 个最重要的特征 我编写了以下代码用于特征选择 其中特征尺寸为
  • Google Fonts 字体无法加载

    我正在尝试将 PT Sans 添加到时事通讯中 但由于某种原因它没有加载我已经复制了几乎所有代码 但它不起作用 我将非常感谢任何可以提供帮助的人 这是 CSS 代码 h1 h2 h3 font family PT Sans sans ser
  • 可执行目标文件和虚拟内存

    我是 Linux 和虚拟内存的初学者 仍在努力理解虚拟内存和可执行对象文件之间的关系 假设我们有一个可执行目标文件a out存储在硬盘驱动器磁盘上 假设最初 a out 有一个 data具有值为 2018 的全局变量的部分 当加载程序运行时