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"
destructor(void * arg)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"
thread_func(void * arg)39 void *thread_func(void *arg) {
40   return reinterpret_cast<void*>(pthread_setspecific(key, arg));
41 }
42 
SpawnThread(uptr iteration)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 
TEST(SanitizerCommon,PthreadDestructorIterations)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 
TEST(SanitizerCommon,IsAccessibleMemoryRange)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