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
23namespace __sanitizer {
24
25static pthread_key_t key;
26static bool destructor_executed;
27
28extern "C"
29void 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
38extern "C"
39void *thread_func(void *arg) {
40  return reinterpret_cast<void*>(pthread_setspecific(key, arg));
41}
42
43static 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
53TEST(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
62TEST(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