From e34bc9cae798da3c01eca891a60d452440e728df Mon Sep 17 00:00:00 2001 From: Peter Griess Date: Thu, 26 Sep 2013 13:27:05 -0500 Subject: [PATCH] Fix test for memory allocators that want to look backwards. Summary: - The NeedleFinderTest.NoSegFault test uses mprotect(2) to ensure that our needle implementations don't peek past the end of memory. However, some memory allocators (e.g. the defaulton OS X) seem to look at the last byte of a page. As a result, if we allocate 2 pages and mark the second as PROT_NONE, then ask the memory allocator for 2 more pages, it may end up peeking at the last byte of the second page, triggering a SIGBUS. To work around this, allocate 8 pages of memory and only mark the second as PROT_NONE. - Clear mprotect(2) bits before freeing memory. Test Plan: - fbconfig -r folly && fbmake runtests - ./configure && make check on Ubuntu/FC/Mac Reviewed By: delong.j@fb.com FB internal diff: D998592 --- folly/test/RangeTest.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/folly/test/RangeTest.cpp b/folly/test/RangeTest.cpp index 445df424..a6fe97e9 100644 --- a/folly/test/RangeTest.cpp +++ b/folly/test/RangeTest.cpp @@ -441,8 +441,7 @@ const size_t kPageSize = 4096; void createProtectedBuf(StringPiece& contents, char** buf) { ASSERT_LE(contents.size(), kPageSize); const size_t kSuccess = 0; - char* tmp; - if (kSuccess != posix_memalign((void**)buf, kPageSize, 2 * kPageSize)) { + if (kSuccess != posix_memalign((void**)buf, kPageSize, 4 * kPageSize)) { ASSERT_FALSE(true); } mprotect(*buf + kPageSize, kPageSize, PROT_NONE); @@ -451,6 +450,11 @@ void createProtectedBuf(StringPiece& contents, char** buf) { contents.reset(*buf + newBegin, contents.size()); } +void freeProtectedBuf(char* buf) { + mprotect(buf + kPageSize, kPageSize, PROT_READ | PROT_WRITE); + free(buf); +} + TYPED_TEST(NeedleFinderTest, NoSegFault) { const string base = string(32, 'a') + string("b"); const string delims = string(32, 'c') + string("b"); @@ -482,8 +486,8 @@ TYPED_TEST(NeedleFinderTest, NoSegFault) { s1.begin(), s1.end()); auto e2 = (f2 == s2.end()) ? StringPiece::npos : f2 - s2.begin(); EXPECT_EQ(r2, e2); - free(buf1); - free(buf2); + freeProtectedBuf(buf1); + freeProtectedBuf(buf2); } } } -- 2.34.1