Splaty
Splaty

Reputation: 634

mmap64() works in Red Hat 6.6 but not in Red Hat 7.2

The function call to mmap64() is as follows:

addr = (unsigned char*) mmap64(NULL, regionSize, PROT_READ|PROT_WRITE, MAP_SHARED, FileDesc, (unsigned long long)regionAddr);

The arguments typically have values as follows:

regionSize = 0x20000;
FileDesc   = 27;
regionAddr = 0x332C0000;

Obviously in the code these values are not hard-coded like that, but I just want to show you what the typical values for them will be.

The problem:

mmap64() call works perfectly in Red Hat Linux 6.6, kernel version: 2.6.32-504.16.2.el6.x86_64. It fails in Red Hat Linux 7.2, kernel version: 3.10.0-327.13.1.el7.x86_64.

No difference in code as far as I'm aware of.

The errno returned is "Invalid argument" or errno #22 (EINVAL). Looking at this reference http://linux.die.net/man/3/mmap64, I see 3 possiblilities for the EINVAL error:

  1. We don't like addr, length, or offset (e.g., they are too large, or not aligned on a page boundary). -> most likely culprit in my situation.
  2. (since Linux 2.6.12) length was 0. -> Impossible, I checked length (regionSize) value in debug print, it was 0x20000.
  3. flags contained neither MAP_PRIVATE or MAP_SHARED, or contained both of these values. -> Can't be this as you can see from my function call, only MAP_SHARED flag was given as argument.

So I'm stuck at the moment. Not sure how to debug this. This problem is 100% reproducible. Anyone have tips on what could have changed between the two OS versions to cause this?

Upvotes: 0

Views: 513

Answers (1)

Jonathan Leffler
Jonathan Leffler

Reputation: 754810

Transferring comments into an answer (with some comments trimmed as not relevant).

Why not simply use mmap() without the suffix if you're building 64-bit executables? Does that make any difference to your problem?

However, I think your problem is what you call regionAddr. The last argument to mmap64() is called offset in the synopsis, and:

offset must be a multiple of the page size as returned by sysconf(_SC_PAGE_SIZE).

Is your value of regionAddr a multiple of the page size? It looks to me like it has too few trailing zeros in the hex (it is a multiple of 512, but not a multiple of 4K or larger).


Note that the question originally had a different value on display for regionAddr — see also the comments below.

regionAddr = 0x858521600;

and

addr = (unsigned char*) mmap64(NULL, regionSize, PROT_READ|PROT_WRITE, MAP_SHARED, FileDesc, (unsigned long long)regionAddr);

With the revised information (that the value in regionAddr is 0x332C0000 or decimal 828521600), it is less than obvious what is going wrong.

Upvotes: 3

Related Questions