Home | History | Annotate | Download | only in tests
      1 //===-- sanitizer_posix_test.cc -------------------------------------------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // Tests for POSIX-specific code.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 #include "sanitizer_common/sanitizer_platform.h"
     15 #if SANITIZER_POSIX
     16 
     17 #include "sanitizer_common/sanitizer_common.h"
     18 #include "gtest/gtest.h"
     19 
     20 #include <pthread.h>
     21 #include <sys/mman.h>
     22 
     23 namespace __sanitizer {
     24 
     25 static pthread_key_t key;
     26 static bool destructor_executed;
     27 
     28 extern "C"
     29 void destructor(void *arg) {
     30   uptr iter = reinterpret_cast<uptr>(arg);
     31   if (iter > 1) {
     32     ASSERT_EQ(0, pthread_setspecific(key, reinterpret_cast<void *>(iter - 1)));
     33     return;
     34   }
     35   destructor_executed = true;
     36 }
     37 
     38 extern "C"
     39 void *thread_func(void *arg) {
     40   return reinterpret_cast<void*>(pthread_setspecific(key, arg));
     41 }
     42 
     43 static void SpawnThread(uptr iteration) {
     44   destructor_executed = false;
     45   pthread_t tid;
     46   ASSERT_EQ(0, pthread_create(&tid, 0, &thread_func,
     47                               reinterpret_cast<void *>(iteration)));
     48   void *retval;
     49   ASSERT_EQ(0, pthread_join(tid, &retval));
     50   ASSERT_EQ(0, retval);
     51 }
     52 
     53 TEST(SanitizerCommon, PthreadDestructorIterations) {
     54   ASSERT_EQ(0, pthread_key_create(&key, &destructor));
     55   SpawnThread(GetPthreadDestructorIterations());
     56   EXPECT_TRUE(destructor_executed);
     57   SpawnThread(GetPthreadDestructorIterations() + 1);
     58   EXPECT_FALSE(destructor_executed);
     59   ASSERT_EQ(0, pthread_key_delete(key));
     60 }
     61 
     62 TEST(SanitizerCommon, IsAccessibleMemoryRange) {
     63   const int page_size = GetPageSize();
     64   uptr mem = (uptr)mmap(0, 3 * page_size, PROT_READ | PROT_WRITE,
     65                         MAP_PRIVATE | MAP_ANON, -1, 0);
     66   // Protect the middle page.
     67   mprotect((void *)(mem + page_size), page_size, PROT_NONE);
     68   EXPECT_TRUE(IsAccessibleMemoryRange(mem, page_size - 1));
     69   EXPECT_TRUE(IsAccessibleMemoryRange(mem, page_size));
     70   EXPECT_FALSE(IsAccessibleMemoryRange(mem, page_size + 1));
     71   EXPECT_TRUE(IsAccessibleMemoryRange(mem + page_size - 1, 1));
     72   EXPECT_FALSE(IsAccessibleMemoryRange(mem + page_size - 1, 2));
     73   EXPECT_FALSE(IsAccessibleMemoryRange(mem + 2 * page_size - 1, 1));
     74   EXPECT_TRUE(IsAccessibleMemoryRange(mem + 2 * page_size, page_size));
     75   EXPECT_FALSE(IsAccessibleMemoryRange(mem, 3 * page_size));
     76   EXPECT_FALSE(IsAccessibleMemoryRange(0x0, 2));
     77 }
     78 
     79 }  // namespace __sanitizer
     80 
     81 #endif  // SANITIZER_POSIX
     82