Mmap () returns the same pointer twice

I'm having a problem with the page distributor that I can't wrap my head around with. The program runs on Ubuntu 14.04 x86_64, and the g ++ --version output says "g ++ (Ubuntu 4.8.2-19ubuntu1) 4.8.2".

My problem is that sometimes I get the same pointer from the mmap () call that I already got from the previous call, without the previous pointer ever being mmunmap (): ed. In one debug session, for example, I successfully allocated 2097152 bytes and got the 0x7fffaa398000 pointer, and then after a while with a bunch of other allocations between me, 12288 bytes were successfully allocated for the same 0x7fffaa398000 pointer. The allocator then proceeds to approve as the account takes on this duplicate entry.

The call looks like this:

void *p = mmap(0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);

      

Is it possible that the pointer will be deallocated in some other way besides munmap ()?

+3


source to share


3 answers


First, if you're using address maps, are you sure you're not conflicting with anything? If you specify an address to match, any existing creature at that location will be discarded and overwritten.



Look for a call munmap()

that removes memory located before that is duplicated, but where it is close enough so that the amount of memory is not removed covers that address. I would venture to say that the pointer and / or display length is probably getting corrupted. If you "exceeded" - munmap()

and / or misalign- munmap()

, the memory will still be disabled, but it will not match the allocated blocks. Start the process in strace

and trace only the calls mmap()

and munmap()

calls to minimize the impact if it is caused by a synchronization problem. Look for munmap()

calls where the address plus the length spans the pointer you see twice.

+1


source


Hmm you will need to check if there is a match, try this or similar. Also there can be a maximum, you can mmap.

warning unverified code ::



std::set<decltype(void *)> mySet;

// On mmap

void *p = mmap(0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
assert(!(p & 0xfff));
auto pp = p;
while (size > 0) {
  if (mySet.count(pp) {
    printf("bug %p\n", pp);
  mySet.insert(pp);
  pp += 4096;
  size -= 4096;
}  

// On unmap

res = unmap(p, size); 
assert(!(p & 0xfff));
auto pp = p;
while (size > 0) {
  if (!mySet.count(pp) {
    printf("bug %p, size %d\n", pp, mySet.size()); // %d or ld???
  mySet.erase(pp);
  pp += 4096;
  size -= 4096;
}  

      

0


source


The call is mmap()

usually passed to the file descriptor / driver in your case -1

(I assume you usually use a valid descriptor). My suggestion is that you look at the driver code, especially the mmap()

driver function, and check the functionality.

Also, look at the output dmesg

if there are any errors / warnings regarding the driver.

-1


source







All Articles