1 //===-- sanitizer_posix_test.cpp ------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // Tests for POSIX-specific code. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "sanitizer_common/sanitizer_platform.h" 14 #if SANITIZER_POSIX 15 16 #include "sanitizer_common/sanitizer_common.h" 17 #include "gtest/gtest.h" 18 19 #include <pthread.h> 20 #include <sys/mman.h> 21 22 namespace __sanitizer { 23 24 static pthread_key_t key; 25 static bool destructor_executed; 26 27 extern "C" 28 void destructor(void *arg) { 29 uptr iter = reinterpret_cast<uptr>(arg); 30 if (iter > 1) { 31 ASSERT_EQ(0, pthread_setspecific(key, reinterpret_cast<void *>(iter - 1))); 32 return; 33 } 34 destructor_executed = true; 35 } 36 37 extern "C" 38 void *thread_func(void *arg) { 39 return reinterpret_cast<void*>(pthread_setspecific(key, arg)); 40 } 41 42 static void SpawnThread(uptr iteration) { 43 destructor_executed = false; 44 pthread_t tid; 45 ASSERT_EQ(0, pthread_create(&tid, 0, &thread_func, 46 reinterpret_cast<void *>(iteration))); 47 void *retval; 48 ASSERT_EQ(0, pthread_join(tid, &retval)); 49 ASSERT_EQ(0, retval); 50 } 51 52 TEST(SanitizerCommon, PthreadDestructorIterations) { 53 ASSERT_EQ(0, pthread_key_create(&key, &destructor)); 54 SpawnThread(GetPthreadDestructorIterations()); 55 EXPECT_TRUE(destructor_executed); 56 SpawnThread(GetPthreadDestructorIterations() + 1); 57 #if SANITIZER_SOLARIS 58 // Solaris continues calling destructors beyond PTHREAD_DESTRUCTOR_ITERATIONS. 59 EXPECT_TRUE(destructor_executed); 60 #else 61 EXPECT_FALSE(destructor_executed); 62 #endif 63 ASSERT_EQ(0, pthread_key_delete(key)); 64 } 65 66 TEST(SanitizerCommon, IsAccessibleMemoryRange) { 67 const int page_size = GetPageSize(); 68 uptr mem = (uptr)mmap(0, 3 * page_size, PROT_READ | PROT_WRITE, 69 MAP_PRIVATE | MAP_ANON, -1, 0); 70 // Protect the middle page. 71 mprotect((void *)(mem + page_size), page_size, PROT_NONE); 72 EXPECT_TRUE(IsAccessibleMemoryRange(mem, page_size - 1)); 73 EXPECT_TRUE(IsAccessibleMemoryRange(mem, page_size)); 74 EXPECT_FALSE(IsAccessibleMemoryRange(mem, page_size + 1)); 75 EXPECT_TRUE(IsAccessibleMemoryRange(mem + page_size - 1, 1)); 76 EXPECT_FALSE(IsAccessibleMemoryRange(mem + page_size - 1, 2)); 77 EXPECT_FALSE(IsAccessibleMemoryRange(mem + 2 * page_size - 1, 1)); 78 EXPECT_TRUE(IsAccessibleMemoryRange(mem + 2 * page_size, page_size)); 79 EXPECT_FALSE(IsAccessibleMemoryRange(mem, 3 * page_size)); 80 EXPECT_FALSE(IsAccessibleMemoryRange(0x0, 2)); 81 } 82 83 } // namespace __sanitizer 84 85 #endif // SANITIZER_POSIX 86