如何检测特定页面是否映射到内存中?
我想检测特定页面是否已映射到内存中。这里的目标是能够在使用固定内存地址调用 mmap 之前执行此检查。以下代码说明了默认情况下在这种情况下会发生的情况: mmap 默默地重新映射原始内存页。
#include <sys/mman.h>
#include <stdio.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
int page_size;
void *ptr;
page_size = getpagesize();
ptr = mmap(0, 10 * page_size, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
if (ptr == MAP_FAILED) {
printf ("map1 failed\n");
return 1;
}
((int *)ptr)[0] = 0xdeadbeaf;
ptr = mmap(ptr, 2 * page_size, PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, 0, 0);
if (ptr == MAP_FAILED) {
printf ("map2 failed\n");
return 1;
}
if (((int *)ptr)[0] != 0xdeadbeaf) {
printf ("oops, data gone !\n");
}
return 0;
}
我知道我可以打开并解析 /proc/self/maps 来找出已分配的内存范围,并从中推断是否可以使用 mmap 安全地请求特定内存范围,但我正在寻找合适的 API:是否有这样的一个东西?
I would like to detect whether or not a specific page has already been mapped in memory. The goal here is to be able to perform this check before calling mmap with a fixed memory address. The following code illustrates what happens in this case by default: mmap silently remaps the original memory pages.
#include <sys/mman.h>
#include <stdio.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
int page_size;
void *ptr;
page_size = getpagesize();
ptr = mmap(0, 10 * page_size, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
if (ptr == MAP_FAILED) {
printf ("map1 failed\n");
return 1;
}
((int *)ptr)[0] = 0xdeadbeaf;
ptr = mmap(ptr, 2 * page_size, PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, 0, 0);
if (ptr == MAP_FAILED) {
printf ("map2 failed\n");
return 1;
}
if (((int *)ptr)[0] != 0xdeadbeaf) {
printf ("oops, data gone !\n");
}
return 0;
}
I understand that I could open and parse /proc/self/maps to figure out which memory range has been allocated and infer from that if I can safely request a specific memory range with mmap but I am looking for a proper API: is there such a thing ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
msync(addr, len, 0) 和检查 ENOMEM 似乎有效(通过相当肤浅的测试)。
msync(addr, len, 0) and checking for ENOMEM seems to work (with a fairly superficial test).
这不会“重新映射”内存,而是在不同的地址创建另一个映射(因为您提供的映射已经被占用,并且无论如何它都被视为提示)。旧的仍然有效,只是因为覆盖了
ptr
变量而丢失了对它的引用。如果您想创建到同一内存的多个映射,请查看
shm_open(2)
。如果您只是想检查地址是否已映射,那么 @MerickOWA 指出的MAP_FIXED
技巧应该有效。编辑 0:
您对
MAP_FIXED
的看法是正确的>,在这种情况下没有帮助。您可以尝试的是mincore(2 )
。它返回的错误之一是:ENOMEM
addr 到 addr + 包含未映射内存的长度。
This doesn't "remap" the memory, but creates another mapping at different address (since the one you give it is already taken, and it's treated as a hint anyway). The old one is still valid, you just lose the reference to it since you overwrite the
ptr
variable.If you want to create multiple mappings to the same memory like that look into
shm_open(2)
.If you just want to check if address is mapped then theMAP_FIXED
trick pointed out by @MerickOWA should work.Edit 0:
You are right about
MAP_FIXED
, it doesn't help in this case. What you might try ismincore(2)
. One of the errors it returns is:ENOMEM
addr to addr + length contained unmapped memory.
在 QNX 上,您可以使用
mem_offset()
和posix_mem_offset()
并检查输出中contig_len
的内容,并将其与length
输入参数。On QNX, you can use
mem_offset()
andposix_mem_offset()
and check the contents ofcontig_len
on output, comparing it with thelength
input parameter.