【问题标题】:Memory does not get allocated with the MAP_ANONYMOUS and MAP_SHARED_VALIDATE flag in mmap()mmap() 中的 MAP_ANONYMOUS 和 MAP_SHARED_VALIDATE 标志未分配内存
【发布时间】:2021-01-28 21:47:20
【问题描述】:

我正在尝试使用 MAP_ANONYMOUS 标志分配内存块,但它没有与 MAP_SHARED_VALIDATE 标志一起创建任何内存块,但带有 MAP_PRIVATE 或 MAP_SHARED 标志的 MAP_ANONYMOUS 会创建内存块。有人可以解释为什么会发生这种情况。

#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <sys/mman.h>
#include <unistd.h>

int main(void)
{
  size_t size = getpagesize();

  errno = 0;
  void *first = mmap(0, size, PROT_READ|PROT_WRITE,
                     MAP_ANONYMOUS|MAP_SHARED_VALIDATE, -1, 0);
  printf("first: %p %s\n", first, strerror(errno));

  errno = 0;
  void *second = mmap(0, size, PROT_READ|PROT_WRITE,
                      MAP_ANONYMOUS|MAP_SHARED, -1, 0);
  printf("second: %p %s\n", second, strerror(errno));

  return 0;
}

已观察到在 Linux 4.19 和 Linux 5.8 上都可以打印,

first: 0xffffffffffffffff Invalid argument
second: 0x7f56b274d000 Success

标志似乎正在准确地传递给内核......

$ strace -e trace=mmap ./a.out 2>&1 | tail -n5
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_SHARED_VALIDATE|MAP_ANONYMOUS, -1, 0) = -1 EINVAL (Invalid argument)
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0) = 0x7fd3145bb000
first: 0xffffffffffffffff Invalid argument
second: 0x7fd3145bb000 Success
+++ exited with 0 +++

【问题讨论】:

  • 在您的代码示例中,mmap 调用之间没有区别(但我不确定您想通过 2 个调用展示什么)。此外,您的 printf 调用访问越界内存,因为您没有提供 %p 格式的参数。如果mmap 返回-1,你应该先查看errno,看看是什么错误。
  • 请注意,第二次调用mmap 可能会更改errno 的值,因此您需要在每次mmap 调用之后立即查看它,类似于:uint8_t *first = mmap(...); printf("first: %p %s\n", (void *)first, strerror(errno));(重复第二次)。
  • 我可以在 Linux 5.8 上重现报告的行为(mmap 失败,而不是 segfault),但我完全不知道为什么。 errnoEINVAL。从手册页中我可以看出,MAP_SHARED_VALIDATE | MAP_ANONYMOUS 应该是标志的有效组合。
  • 你的内核支持MAP_SHARED_VALIDATE吗?手册页显示“自 Linux 4.15 起”。
  • @AndrewHenle 编辑成问题。

标签: c linux unix mmap


【解决方案1】:

查看linux/mm/mmap.c(内核版本5.9)中的do_mmapMAP_SHARED_VALIDATE 似乎仅支持文件支持的映射(请参阅if (file)else 部分)。我不知道这是一个错误还是故意的。

编辑:我已经提交了bug report

【讨论】:

  • 这似乎是一个错误。当然,手册页没有给出任何关于这种行为的提示。
  • @NateEldredge 我还是提交了错误报告。 :)
猜你喜欢
  • 2016-03-06
  • 2014-07-12
  • 1970-01-01
  • 2016-06-03
  • 2018-08-21
  • 2017-12-20
  • 1970-01-01
  • 2010-12-30
  • 2017-12-15
相关资源
最近更新 更多