用户进程的有效地址空间是多少? (OS X 和 Linux)
mmap
系统调用文档指出,如果出现以下情况,该函数将失败:
指定了 MAP_FIXED 并且地址 参数未对齐页面或部分 所需地址空间的驻留 超出了有效地址空间 用户进程。
我无法在任何地方找到说明什么是有效映射地址的文档。 (我有兴趣在 OS X 和 Linux 上执行此操作,理想情况下相同的地址对两者都有效......)。
The mmap
system call documentation says that the function will fail if:
MAP_FIXED was specified and the addr
argument was not page aligned, or part
of the desired address space resides
out of the valid address space for a
user process.
I can't find documentation anywhere saying what would be a valid address to map. (I'm interested in doing this on OS X and linux, ideally the same address would be valid for both...).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
Linux 内核为自己保留了部分虚拟地址空间,用户空间(几乎)无法访问并且无法映射任何内容。您正在寻找所谓的“用户空间/内核空间分割”。
在 i386 架构上,默认值为 3G/1G 之一——用户空间获得较低的 3 GB 虚拟地址空间,内核获得较高的 1 GB,此外还有 2G/2G 和 1G/3G 分割:
在 x86_64 上,用户空间位于虚拟地址空间的下半部分(目前) 48位虚拟地址空间:
Linux kernel reserves part of virtual address space for itself to where userspace have (almost) no access and can't map anything. You're looking for what's called "userspace/kernelspace split".
On i386 arch default is 3G/1G one -- userspace gets lower 3 GB of virtual address space, kernel gets upper 1 GB, additionally there are 2G/2G and 1G/3G splits:
On x86_64, userspace lives in lower half of (currently) 48-bit of virtual address space:
这取决于许多因素,其中许多因素不受您的控制。正如 adobriyan 提到的,根据操作系统的不同,您有各种固定的上限,超出该上限的内核代码和数据。通常,在 32 位操作系统上,此上限至少为 2GB;某些操作系统提供额外的地址空间。 64 位操作系统通常提供由 CPU 支持的虚拟地址位数控制的上限(通常至少有 40 位地址空间)。然而,还有其他因素是您无法控制的:
/proc/sys/vm/mmap_min_addr
中配置的地址下方的 mmap 映射将被拒绝。malloc
可以自行执行 mmap,这些映射被放置在任意位置因此,无法绝对保证
MAP_FIXED
会成功,因此通常应该应避免。我见过的唯一需要
MAP_FIXED
的地方是在 wine 启动代码中,它保留(使用MAP_FIXED
)所有 2G 以上的地址,以避免混淆 Windows 代码它假设任何映射都不会显示为负地址。当然,这是旗帜的高度专业化用途。如果您尝试这样做是为了避免处理共享内存中的偏移量,一种选择是将指针包装在类中以自动处理偏移量:
注意:这是未经测试的代码,但应该为您提供基本概念。
This varies based on a number of factors, many of which aren't under your control. As adobriyan mentioned, depending on the OS, you have various fixed upper limits, beyond which kernel code and data lies. Usually this upper limit is at least 2GB on 32-bit OSes; some OSes provide additional address space. 64-bit OSes generally provide an upper limit controlled by the number of virtual address bits supported by your CPU (usually at least 40 bits worth of address space). However there are yet other factors beyond your control:
/proc/sys/vm/mmap_min_addr
will be denied.malloc
may perform mmaps on its own, which are placed in a somewhat arbitrary locationAs such, there is no way to absolutely guarentee that
MAP_FIXED
will succeed, and so it should normally be avoided.The only place I've seen where
MAP_FIXED
is necessary is in the wine startup code, which reserves (usingMAP_FIXED
) all addresses above 2G, in order to avoid confusing windows code which assumes no mappings will ever show up with a negative address. This is, of course, a highly specialized use of the flag.If you're trying to do this in order to avoid having to deal with offsets in shared memory, one option would be to wrap pointers in a class to automatically handle offsets:
Note: This is untested code, but should give you the basic idea.