]>
Commit | Line | Data |
---|---|---|
1a4d82fc JJ |
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> | |
92a42be0 | 21 | #include <sys/mman.h> |
1a4d82fc JJ |
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)); | |
92a42be0 | 55 | SpawnThread(GetPthreadDestructorIterations()); |
1a4d82fc | 56 | EXPECT_TRUE(destructor_executed); |
92a42be0 | 57 | SpawnThread(GetPthreadDestructorIterations() + 1); |
1a4d82fc | 58 | EXPECT_FALSE(destructor_executed); |
5bcae85e | 59 | ASSERT_EQ(0, pthread_key_delete(key)); |
1a4d82fc JJ |
60 | } |
61 | ||
92a42be0 SL |
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 | ||
1a4d82fc JJ |
79 | } // namespace __sanitizer |
80 | ||
81 | #endif // SANITIZER_POSIX |