簡體   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