基本的mmap(2)调用失败

时间:2016-12-26 16:54:22

标签: c linux mmap

我已经在这个非常基本的代码上拉了几个小时,我还没有理解为什么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

[1] http://man7.org/linux/man-pages/man2/mmap.2.html

1 个答案:

答案 0 :(得分:5)

strace你的程序时,我看到:

  

mmap(NULL,204800,PROT_READ | PROT_WRITE,MAP_FILE | MAP_ANONYMOUS,-1,0)= -1 EINVAL(无效参数)

您忘记了MAP_SHARED标记(或MAP_PRIVATE标记)。有了它(MAP_SHAREDMAP_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)。你会学到很多东西。