0

ビルドの 1 つで OS を Centos 5.3 32 ビットから Centos 5.5 32 ビットにアップグレードしていました。パッケージの更新を行った後、再起動し、ソースのクリーン コピーをチェックアウトし、ビルドして単体テストを実行しました。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
4

1 に答える 1

2

MAP_GROWSDOWN が glibc http://bugs.centos.org/view.php?id=4767から削除されたようで、使用すべきではありません。

于 2011-04-13T20:29:05.673 に答える