如何检测特定页面是否映射到内存中?

时间:2011-12-02 21:13:55

标签: c linux unix mmap

我想检测特定页面是否已在内存中映射。这里的目标是能够在使用固定内存地址调用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:有这样的事吗?

3 个答案:

答案 0 :(得分:6)

msync(addr,len,0)和检查ENOMEM似乎有效(使用相当肤浅的测试)。

答案 1 :(得分:3)

这不会“重新映射”内存,但会在不同的地址创建另一个映射(因为您提供的映射已经被占用,并且无论如何它被视为提示)。旧版本仍然有效,因为您覆盖了ptr变量,就会丢失对它的引用。

如果要创建多个映射到同一个内存,就像查看shm_open(2)一样。

如果您只想检查地址是否已映射,那么@MerickOWA指出的MAP_FIXED技巧应该有效。

编辑0:

你对MAP_FIXED是正确的,在这种情况下它没有帮助。你可能会尝试mincore(2)。它返回的错误之一是:

<强> ENOMEM addr to addr + length contained unmapped memory.

答案 2 :(得分:0)

在QNX上,您可以使用mem_offset()posix_mem_offset()并检查输出中contig_len的内容,并将其与length输入参数进行比较。

相关问题