Commit e34bc9ca authored by Peter Griess's avatar Peter Griess

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
parent 2549fb3c
...@@ -441,8 +441,7 @@ const size_t kPageSize = 4096; ...@@ -441,8 +441,7 @@ const size_t kPageSize = 4096;
void createProtectedBuf(StringPiece& contents, char** buf) { void createProtectedBuf(StringPiece& contents, char** buf) {
ASSERT_LE(contents.size(), kPageSize); ASSERT_LE(contents.size(), kPageSize);
const size_t kSuccess = 0; const size_t kSuccess = 0;
char* tmp; if (kSuccess != posix_memalign((void**)buf, kPageSize, 4 * kPageSize)) {
if (kSuccess != posix_memalign((void**)buf, kPageSize, 2 * kPageSize)) {
ASSERT_FALSE(true); ASSERT_FALSE(true);
} }
mprotect(*buf + kPageSize, kPageSize, PROT_NONE); mprotect(*buf + kPageSize, kPageSize, PROT_NONE);
...@@ -451,6 +450,11 @@ void createProtectedBuf(StringPiece& contents, char** buf) { ...@@ -451,6 +450,11 @@ void createProtectedBuf(StringPiece& contents, char** buf) {
contents.reset(*buf + newBegin, contents.size()); contents.reset(*buf + newBegin, contents.size());
} }
void freeProtectedBuf(char* buf) {
mprotect(buf + kPageSize, kPageSize, PROT_READ | PROT_WRITE);
free(buf);
}
TYPED_TEST(NeedleFinderTest, NoSegFault) { TYPED_TEST(NeedleFinderTest, NoSegFault) {
const string base = string(32, 'a') + string("b"); const string base = string(32, 'a') + string("b");
const string delims = string(32, 'c') + string("b"); const string delims = string(32, 'c') + string("b");
...@@ -482,8 +486,8 @@ TYPED_TEST(NeedleFinderTest, NoSegFault) { ...@@ -482,8 +486,8 @@ TYPED_TEST(NeedleFinderTest, NoSegFault) {
s1.begin(), s1.end()); s1.begin(), s1.end());
auto e2 = (f2 == s2.end()) ? StringPiece::npos : f2 - s2.begin(); auto e2 = (f2 == s2.end()) ? StringPiece::npos : f2 - s2.begin();
EXPECT_EQ(r2, e2); EXPECT_EQ(r2, e2);
free(buf1); freeProtectedBuf(buf1);
free(buf2); freeProtectedBuf(buf2);
} }
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment