Mmap()返回相同的指针两次

mmap() returns same pointer twice

本文关键字:两次 指针 返回 Mmap      更新时间:2023-10-16

我遇到了一个页面分配器的问题,我无法理解。该程序在Ubuntu 14.04 x86_64上运行,g++——版本输出显示"g++ (Ubuntu 4.8.2-19ubuntu1) 4.8.2"。

我的问题是,有时,我从mmap()调用中收到了我已经从先前的调用中收到的相同的指针,而以前的指针从未被mmunmap():ed。例如,在一个调试会话中,我成功地分配了2097152个字节,并获得了指针0x7fffaa398000,然后一段时间后,在其他一些分配中,我成功地为同一个指针0x7fffaa398000分配了12288个字节。分配器接着进行断言,因为簿记注意到了这个双条目。

调用是这样的:

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

指针是否可能以其他方式获得释放,而不是munmap()?

首先,如果强制映射地址,您确定不会与任何内容冲突吗?如果您为映射指定了一个地址,那么该位置的任何先前存在的映射都将被丢弃并覆盖。

查找在被复制的指针之前取消映射位于的内存的munmap()调用,但是它足够接近以至于未映射的内容量覆盖了所讨论的地址。我冒昧地说,很可能是指针和/或映射长度被损坏了。如果您"over"- munmap()和/或不对齐- munmap(),内存仍然会被取消映射,但它不会对应于您分配的块。在strace下运行进程,并且只跟踪 mmap()munmap()调用,以尽量减少由时间问题引起的影响。查找munmap()调用,其中地址加长度覆盖了您看到映射两次的指针。

嗯,你需要检查有没有重叠,试试这个或类似的。也可能有一个你可以映射的最大值。

警告未测试代码::

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 %pn", 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 %dn", pp, mySet.size()); // %d or ld???
  mySet.erase(pp);
  pp += 4096;
  size -= 4096;
}  

mmap()调用通常传递给文件描述符/驱动程序,在您的情况下是-1(我假设您通常使用有效的描述符)。我的建议是,您查看驱动程序的代码,特别是驱动程序的mmap()函数,并验证其功能。

另外查看dmesg输出,如果有任何关于驱动程序的错误/警告。