//===-- sanitizer_posix_test.cc -------------------------------------------===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // Tests for POSIX-specific code. // //===----------------------------------------------------------------------===// #include "sanitizer_common/sanitizer_platform.h" #if SANITIZER_POSIX #include "sanitizer_common/sanitizer_common.h" #include "gtest/gtest.h" #include <pthread.h> #include <sys/mman.h> namespace __sanitizer { static pthread_key_t key; static bool destructor_executed; extern "C" void destructor(void *arg) { uptr iter = reinterpret_cast<uptr>(arg); if (iter > 1) { ASSERT_EQ(0, pthread_setspecific(key, reinterpret_cast<void *>(iter - 1))); return; } destructor_executed = true; } extern "C" void *thread_func(void *arg) { return reinterpret_cast<void*>(pthread_setspecific(key, arg)); } static void SpawnThread(uptr iteration) { destructor_executed = false; pthread_t tid; ASSERT_EQ(0, pthread_create(&tid, 0, &thread_func, reinterpret_cast<void *>(iteration))); void *retval; ASSERT_EQ(0, pthread_join(tid, &retval)); ASSERT_EQ(0, retval); } TEST(SanitizerCommon, PthreadDestructorIterations) { ASSERT_EQ(0, pthread_key_create(&key, &destructor)); SpawnThread(GetPthreadDestructorIterations()); EXPECT_TRUE(destructor_executed); SpawnThread(GetPthreadDestructorIterations() + 1); EXPECT_FALSE(destructor_executed); ASSERT_EQ(0, pthread_key_delete(key)); } TEST(SanitizerCommon, IsAccessibleMemoryRange) { const int page_size = GetPageSize(); uptr mem = (uptr)mmap(0, 3 * page_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0); // Protect the middle page. mprotect((void *)(mem + page_size), page_size, PROT_NONE); EXPECT_TRUE(IsAccessibleMemoryRange(mem, page_size - 1)); EXPECT_TRUE(IsAccessibleMemoryRange(mem, page_size)); EXPECT_FALSE(IsAccessibleMemoryRange(mem, page_size + 1)); EXPECT_TRUE(IsAccessibleMemoryRange(mem + page_size - 1, 1)); EXPECT_FALSE(IsAccessibleMemoryRange(mem + page_size - 1, 2)); EXPECT_FALSE(IsAccessibleMemoryRange(mem + 2 * page_size - 1, 1)); EXPECT_TRUE(IsAccessibleMemoryRange(mem + 2 * page_size, page_size)); EXPECT_FALSE(IsAccessibleMemoryRange(mem, 3 * page_size)); EXPECT_FALSE(IsAccessibleMemoryRange(0x0, 2)); } } // namespace __sanitizer #endif // SANITIZER_POSIX