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

时间:2015-05-29 08:36:55

标签: c++ linux gcc x86-64 mmap

我遇到了一个页面分配器的问题,我无法解决这个问题。该程序在Ubuntu 14.04 x86_64上运行,g ++ --version输出显示“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()以外的其他方式解除分配?

3 个答案:

答案 0 :(得分:1)

首先,如果您要强制映射地址,您确定不会与任何内容发生冲突吗?如果您正在为映射指定地址,则该位置上的任何预先存在的映射都将被丢弃并覆盖。

寻找一个munmap()调用,取消内存位于之前重复指针的内存,但是它已足够接近以至于未映射的内存量覆盖了相关地址。我冒昧地说它可能是指针和/或映射长度被破坏了。如果你" over " - munmap()和/或错位 - munmap(),内存仍然会被取消映射,但它赢了& #39; t对应于您分配的块。在strace下运行您的流程,并跟踪 mmap()munmap()来电,以最大限度地减少因时间问题导致的影响。查找munmap()次调用,其中地址加上长度覆盖了您看到两次映射的指针。

答案 1 :(得分:0)

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

警告未经测试的代码::

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;
}  

答案 2 :(得分:-1)

public void GetData() { string connStr = ConfigurationManager.ConnectionStrings["CRM_SQL"].ConnectionString; SqlConnection conn = new SqlConnection(connStr); conn.Open(); SqlCommand query = new SqlCommand(chart.Sql, conn); SqlDataReader rst = query.ExecuteReader(); gridView1.DataSource = rst; gridView1.DataBind(); } 调用通常传递给文件描述符/驱动程序,在您的情况下mmap()(我假设您通常使用有效的描述符)。 我的建议是,你看一下驱动程序的代码,特别是驱动程序的-1函数,并验证功能。

如果有任何关于驱动程序的错误/警告,请查看mmap()输出。