我正在使用linux内核中的一些常用命令,并且看到mprotect()被使用了很多次。我只是想知道,mprotect()用来找出它为其设置保护值的内存地址的决定因素是什么?在它自己的地址空间中?
答案 0 :(得分:9)
在MMU 1 的体系结构上,mprotect()
作为参数的地址是虚拟地址。每个进程都有自己独立的虚拟地址空间,因此只有两种可能:
mprotect()
通过改变附加到VMA 2 的标志来内部工作。它必须做的第一件事是查找与传递的地址相对应的VMA - 如果传递的地址在内核的地址范围内,那么 no VMA,因此该搜索将失败。如果您尝试更改未映射的地址空间区域上的保护,则会发生同样的情况。
通过检查/proc/<pid>/smaps
或/proc/<pid>/maps
,您可以在流程的地址空间中看到VMA的表示。
<小时/> 1。记忆管理单位
答案 1 :(得分:3)
这是virtual memory。关于dynamic linker/loader。您在跟踪中看到的大多数mprotect(2)
系统调用可能与引入库依赖关系有关,但malloc(3)
实现也可能会调用它。
要在评论中回答您的问题 - MMU和内核中的代码保护一个进程与另一个进程。每个进程都有一个完整的32位或64位地址空间的错觉。 操作的地址虚拟属于给定进程。内核在硬件的帮助下将这些内容映射到物理内存页面。这些页面可以隐式地作为代码在进程之间共享,或者显式地用于进程间通信。
答案 2 :(得分:3)
内核在当前进程的页表中查找您传递mprotect的地址。如果它不在那里则失败。如果它在那里,内核可能会尝试使用新的访问权限标记页面。我不确定,但如果有一些特殊原因导致无法授予访问权限(例如尝试将内存映射共享文件区域的权限更改为可写),则内核可能仍会在此处返回错误当文件实际上只读时。)
请记住,处理器用来确定内存区域是否可访问的页表不是内核用来查找该地址的页表。处理器的表可能有空洞,用于替换为磁盘的页面。这些表是相关的,但不一样。