Basic mmap(2) call fails

1.5k Views Asked by At

I've been pulling my hairs out for hours on this very basic piece of code and I haven't managed to understand why mmap(2) was failing.

#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");
}

But when I run it:

$ make mmap
cc     mmap.c   -o mmap
$ ./mmap 
DEBUG: mmap(0, 204800, 0x3, 0x20, -1, 0)
mmap: mmap: Invalid argument

I checked and re-checked mmap(2)'s manpage [1], and it seems that all requirements are OK but I must be missing something. I'm running Linux kernel 4.8.13.

Thanks. -- Jeremie

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

1

There are 1 best solutions below

0
On

When strace ing your program, I see:

mmap(NULL, 204800, PROT_READ|PROT_WRITE, MAP_FILE|MAP_ANONYMOUS, -1, 0) = -1 EINVAL (Invalid argument)

You forgot a MAP_SHARED flag (or a MAP_PRIVATE one). With it (either MAP_SHARED or MAP_PRIVATE, but you need one of them) your program works:

    slab = mmap(NULL, SLABSIZE, PROT_READ | PROT_WRITE, 
                MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);

Quoting the mmap(2) man page:

This behavior is determined by including exactly one of the following values in flags:

(emphasis is mine)

  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.

So the general advice before pulling your hairs: read once again the documentation; take a nap; read another time the documentation and think about what did you miss.

Another hint would be to use strace(1) on some (or several) existing executable(s). You'll learn a lot.