繁体   English   中英

升级到Centos 5.5后,为什么MAP_GROWSDOWN会导致SIGBUS错误?

[英]Why does MAP_GROWSDOWN cause SIGBUS errors after upgrading to Centos 5.5?

我正在将其中一个版本的操作系统从Centos 5.3 32bit升级到Centos 5.5 32bit。 完成软件包更新后,我重新启动,签出了源的干净副本,构建并运行了单元测试。 所有依赖于我们的MemMap基类的单元测试都开始失败。

当我们在映射内存后立即尝试设置保护页面的值时,发生崩溃。 在探索之后,我能够将问题与我们使用的MAP_GROWSDOWN标志隔离开来,测试运行没有它,但在设置标志时崩溃。 当构建系统运行5.3时,这些测试工作正常,但是当我们升级到5.5时,立即开始崩溃。 它们也适用于我的开发机器,它也运行5.5但是真正的硬件; 构建系统是XEN VM。 这是一个稳定的代码,在几个版本中没有被修改,并且单元测试覆盖率在80%以上。

所以我想我的问题是为什么会发生这种情况?

int flags = MAP_ANONYMOUS|MAP_PRIVATE|MAP_GROWSDOWN;
int prot = PROT_EXEC|PROT_READ|PROT_WRITE;
size_t length = 524288;

long rv = ::sysconf(_SC_PAGESIZE);
if (rv < 0)
    throw SystemException(errno);
size_t pagelength = size_t(rv);

//  Adjust length for guard page
length = pagelength * (((length + pagelength - 1) / pagelength) + 1);

m_addr = ::mmap(NULL, length, prot, flags, -1, 0);
if (m_addr == MAP_FAILED)
    throw SystemException(errno);

m_stackaddr = static_cast<void *>(static_cast<char *>(m_addr) + pagelength);
m_length = length - pagelength;

// Fill the guard page with an interesting pattern
unsigned int *g = static_cast<unsigned int *>(m_addr);
for (size_t i=0; i < pagelength; i += sizeof(unsigned int))
    *g++ = 0xBADC0FFEU;  <-- SIGBUS HAPPENS HERE ON FIRST ITERATION

似乎MAP_GROWSDOWN已从glibc http://bugs.centos.org/view.php?id=4767中删除,因此不应使用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM