我已经在这个非常基本的代码上拉了几个小时,我还没有理解为什么mmap(2)失败了。
#include <sys/mman.h>
#include <sys/user.h>
#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#define NPAGES 50
#define SLABSIZE (PAGE_SIZE * NPAGES) // 200 kB
int
main(int argc, char *argv[])
{
char *slab;
printf("DEBUG: mmap(%#x, %u, %#x, %#x, %d, %u)\n",
NULL, SLABSIZE, PROT_READ | PROT_WRITE, MAP_ANON, -1, 0);
slab = mmap(NULL, SLABSIZE, PROT_READ | PROT_WRITE, MAP_ANON, -1, 0);
if (slab == MAP_FAILED)
err(1, "mmap");
}
但是当我运行它时:
$ make mmap
cc mmap.c -o mmap
$ ./mmap
DEBUG: mmap(0, 204800, 0x3, 0x20, -1, 0)
mmap: mmap: Invalid argument
我检查并重新检查了mmap(2)的联机帮助页[1],似乎所有要求都没问题,但我必须遗漏一些东西。 我正在运行Linux内核4.8.13。
感谢。 - Jeremie
答案 0 :(得分:5)
当strace
你的程序时,我看到:
mmap(NULL,204800,PROT_READ | PROT_WRITE,MAP_FILE | MAP_ANONYMOUS,-1,0)= -1 EINVAL(无效参数)
您忘记了MAP_SHARED
标记(或MAP_PRIVATE
标记)。有了它(MAP_SHARED
或MAP_PRIVATE
,但你需要其中一个)你的程序可以运行:
slab = mmap(NULL, SLABSIZE, PROT_READ | PROT_WRITE,
MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
引用mmap(2)手册页:
此行为是通过在flags中包含 完全以下值之一来确定的:
(重点是我的)
MAP_SHARED Share this mapping. Updates to the mapping are visible to other processes mapping the same region, and (in the case of file-backed mappings) are carried through to the underlying file. (To precisely control when updates are carried through to the underlying file requires the use of msync(2).) MAP_PRIVATE Create a private copy-on-write mapping. Updates to the mapping are not visible to other processes mapping the same file, and are not carried through to the underlying file. It is unspecified whether changes made to the file after the mmap() call are visible in the mapped region.
所以在拉扯你的头发之前的一般建议:再次阅读文档;小睡一下;再读一遍文档并思考你错过了什么。
另一个提示是在某些(或几个)现有可执行文件上使用strace(1)。你会学到很多东西。