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.
我想检测一个特定的页面是否已经被映射到内存中。这里的目标是能够在调用具有固定内存地址的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;
}
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 ?
我理解我可以打开并解析/proc/self/maps,以确定已经分配了哪些内存范围,并由此推断,如果我可以安全地使用mmap请求一个特定的内存范围,但我正在寻找一个合适的API:是否存在这种情况?
3 个解决方案
#1
6
msync(addr, len, 0) and checking for ENOMEM seems to work (with a fairly superficial test).
msync(addr, len, 0)和ENOMEM检查似乎是有效的(通过一个相当肤浅的测试)。
#2
3
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.
这并不是“重新映射”内存,而是在不同的地址创建另一个映射(因为您给出的那个地址已经被占用了,而且无论如何它都被当作一个提示)。旧的仍然有效,因为覆盖了ptr变量,所以就失去了对它的引用。
If you want to create multiple mappings to the same memory like that look into shm_open(2)
.
如果您想创建到相同内存的多个映射,请查看shm_open(2)。
If you just want to check if address is mapped then the MAP_FIXED
trick pointed out by @MerickOWA should work.
如果您只是想检查地址是否被映射,那么@MerickOWA指出的MAP_FIXED方法应该可以工作。
Edit 0:
You are right about MAP_FIXED
, it doesn't help in this case. What you might try is mincore(2)
. One of the errors it returns is:
关于MAP_FIXED,您是对的,在这种情况下没有帮助。你可以试试mincore(2)。它返回的错误之一是:
ENOMEM
addr to addr + length contained unmapped memory.
ENOMEMaddr到addr +长度包含未映射内存。
#3
0
On QNX, you can use mem_offset()
and posix_mem_offset()
and check the contents of contig_len
on output, comparing it with the length
input parameter.
在QNX上,可以使用mem_offset()和posix_mem_offset()检查输出上的contig_len的内容,并将其与长度输入参数进行比较。
#1
6
msync(addr, len, 0) and checking for ENOMEM seems to work (with a fairly superficial test).
msync(addr, len, 0)和ENOMEM检查似乎是有效的(通过一个相当肤浅的测试)。
#2
3
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.
这并不是“重新映射”内存,而是在不同的地址创建另一个映射(因为您给出的那个地址已经被占用了,而且无论如何它都被当作一个提示)。旧的仍然有效,因为覆盖了ptr变量,所以就失去了对它的引用。
If you want to create multiple mappings to the same memory like that look into shm_open(2)
.
如果您想创建到相同内存的多个映射,请查看shm_open(2)。
If you just want to check if address is mapped then the MAP_FIXED
trick pointed out by @MerickOWA should work.
如果您只是想检查地址是否被映射,那么@MerickOWA指出的MAP_FIXED方法应该可以工作。
Edit 0:
You are right about MAP_FIXED
, it doesn't help in this case. What you might try is mincore(2)
. One of the errors it returns is:
关于MAP_FIXED,您是对的,在这种情况下没有帮助。你可以试试mincore(2)。它返回的错误之一是:
ENOMEM
addr to addr + length contained unmapped memory.
ENOMEMaddr到addr +长度包含未映射内存。
#3
0
On QNX, you can use mem_offset()
and posix_mem_offset()
and check the contents of contig_len
on output, comparing it with the length
input parameter.
在QNX上,可以使用mem_offset()和posix_mem_offset()检查输出上的contig_len的内容,并将其与长度输入参数进行比较。