memory-management - 访问分配区域外内存的进程
问题描述
假设一个进程被分配了一个虚拟内存区域。如果进程碰巧访问了该分配区域之外的内存区域,处理器将如何反应?
处理器会杀死进程吗?还是会引发故障?
先感谢您。
解决方案
进程并没有真正分配到某个虚拟内存区域。它们被分配了可以使用虚拟内存访问的物理帧。进程可以虚拟访问所有可用的虚拟内存。
当高级语言被编译时,它被放置在一个可执行文件中。该可执行文件是一种文件格式,它指定了几项内容,其中包括程序使用的虚拟内存。当操作系统启动该可执行文件时,它会将某些物理页面分配给新创建的进程。这些页面包含实际代码。操作系统需要设置页表,以便进程使用的虚拟地址被翻译到内存中的正确位置(正确的物理地址)。
当一个进程试图在它不应该跳转到的虚拟地址处无处跳转时,可能会发生几件事。这是未定义的行为。
如 osdev.org ( https://wiki.osdev.org/Paging ) 所述:
当进程试图访问未映射到任何物理内存的虚拟内存区域时,当尝试在只读页面上写入时,当使用保留位访问 PTE 或 PDE 时,会导致页面错误异常当权限不足时。
CPU 在触发缺页异常之前将错误代码压入堆栈。异常处理程序必须分析错误代码以确定如何处理异常。异常代码的低 3 位是唯一使用的,第 3-31 位是保留的。
这实际上取决于您使用的语言,并且有几个因素起作用。例如,在汇编中,如果您尝试在 RAM 中跳转到随机虚拟地址。可能会发生几件事。
如果您跳转到分配的页面,则该页面可能包含任何内容。它也可以包含零。如果它包含零,则进程将继续执行指令,直到它到达 RAM 中不存在的页面并触发页面错误。或者它也可以最终执行一个 jmp 到 RAM 中的其他地方并最终触发页面错误。
如果跳转到当前位未设置的页面(未分配页面),则 CPU 将立即触发页面错误。由于页面没有分配,它不会神奇地被分配。操作系统需要采取行动。如果该页面应该被进程访问,那么它可能被交换到硬盘并且操作系统需要将它交换回 RAM。如果它不应该被访问(就像在这种情况下),操作系统需要终止进程(它确实如此)。操作系统通过查看该进程的内存映射来知道该进程不应访问该页面。它不应该只是盲目地将页面分配给无处可去的进程。如果进程在执行期间需要更多内存,它可以使用系统调用正确地询问操作系统。
如果您跳转到一个虚拟地址,一旦 MMU 使用页表翻译,该地址以内核模式代码(管理程序代码)进入 RAM,CPU 将使用管理程序触发页面错误并显示错误代码(1 0 1)。
操作系统使用 2 级权限(0 和 3)。因此,所有用户模式进程都以权限 3 运行。除了页表的设置方式之外,没有什么能阻止一个用户进程访问内存和另一个进程的代码。页表通常没有完全填满。如果你跳转到一个随机的虚拟地址,任何事情都可能发生。虚拟地址可以翻译成任何东西。
推荐阅读
- c++ - DeviceIoControl 协助
- html - html电子邮件中的照片不断切断
- c++ - C++ LNK2001 尝试使用外部变量时出错
- doctrine-orm - 尝试删除子行时出现外键错误
- excel - For循环在VBA中找不到价值
- sql-server - 作业和 sp_MSForEachTable 中的 SET QUOTED_IDENTIFIER 错误
- ios - 为什么我的 Swift iOS 构建会出错:“在范围内找不到‘睡眠’”
- javascript - 类访问的多个父 div 的子 div 不会被 .hide() 隐藏
- google-apps-script - 我设置了一个 Google Apps 脚本来自动归档旧电子邮件。它曾经可以工作,但现在我收到授权错误
- regex - 多天读取多个通配符文件模式 - pyspark