0
我在CentOS 5.3 32bit到Centos 5.5 32bit之间升级操作系统。完成软件包更新后,我重新启动,检出源代码的干净副本,构建并运行单元测试。所有依赖MemMap基类的单元测试都开始失败。为什么升级到Centos 5.5后MAP_GROWSDOWN会导致SIGBUS错误?
当我们尝试在映射内存之后立即设置防护页的值时发生崩溃。经过四处探查,我能够将问题隔离到我们使用MAP_GROWSDOWN标志,测试运行良好,但没有它,但在设置标志时崩溃。当构建系统运行5.3时,这些测试正常运行,但是当我们升级到5.5时立即崩溃。他们也在我的开发机器上运行良好,它也运行在5.5版本上,但是是真正的硬件;构建系统是一个XEN虚拟机。这是一段稳定的代码,它在几个版本中没有被修改,并且单元测试覆盖率在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”的目的是什么? – ephemient 2010-10-30 04:34:14