[英]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.