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