我遇到了一个页面分配器的问题,我无法解决这个问题。该程序在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()以外的其他方式解除分配?
答案 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()
输出。