Centos 5.5にアップグレードした後、MAP_GrowsDownがSigbusエラーを引き起こすのはなぜですか?
-
27-09-2019 - |
質問
Centos 5.3 32ビットからCentos 5.5 32ビットにビルドの1つでOSをアップグレードしていました。パッケージの更新を行った後、私は再起動し、ソースのクリーンなコピーをチェックアウトし、ユニットテストを構築して実行しました。 Memmap Baseクラスに依存するすべてのユニットテストは失敗し始めました。
クラッシュは、メモリをマッピングした後すぐにガードページの値を設定しようとすると発生します。周りを突っ込んだ後、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 そして、使用すべきではありません。
所属していません StackOverflow