Files
clang-p2996/compiler-rt/lib/sanitizer_common/tests/sanitizer_posix_test.cpp
Rainer Orth f98a153c8d [sanitizer_common][tests] Fix SanitizerCommon-Unit :: ./Sanitizer-*-Test/SanitizerCommon.PthreadDestructorIterations on Solaris
SanitizerCommon.PthreadDestructorIterations currently FAILs on Solaris:

  [ RUN      ] SanitizerCommon.PthreadDestructorIterations
  /vol/llvm/src/compiler-rt/local/lib/sanitizer_common/tests/sanitizer_posix_test.cc:58: Failure
  Value of: destructor_executed
    Actual: true
  Expected: false
  [  FAILED  ] SanitizerCommon.PthreadDestructorIterations (1 ms)

It turns out that destructor is called 4 times after the first call to SpawnThread, but
5 times after the second.  While PTHREAD_DESTRUCTOR_ITERATIONS is 4 in
<limits.h>, the Solaris pthread_key_create(3C) man page documents

  If, after all the destructors have been called for all keys  with  non-
  null  values,  there  are  still  some  keys  with non-null values, the
  process will be repeated. POSIX requires that this process be  executed
  at   least   PTHREAD_DESTRUCTOR_ITERATIONS  times.  Solaris  calls  the
  destructors repeatedly until all values with associated destructors are
  NULL. Destructors that set new values can cause an infinite loop.

The patch adjusts the test case to allow for this.

Tested on x86_64-pc-solaris2.11.

Differential Revision: https://reviews.llvm.org/D65055

llvm-svn: 367705
2019-08-02 18:55:22 +00:00

86 lines
2.7 KiB
C++

//===-- sanitizer_posix_test.cpp ------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// Tests for POSIX-specific code.
//
//===----------------------------------------------------------------------===//
#include "sanitizer_common/sanitizer_platform.h"
#if SANITIZER_POSIX
#include "sanitizer_common/sanitizer_common.h"
#include "gtest/gtest.h"
#include <pthread.h>
#include <sys/mman.h>
namespace __sanitizer {
static pthread_key_t key;
static bool destructor_executed;
extern "C"
void destructor(void *arg) {
uptr iter = reinterpret_cast<uptr>(arg);
if (iter > 1) {
ASSERT_EQ(0, pthread_setspecific(key, reinterpret_cast<void *>(iter - 1)));
return;
}
destructor_executed = true;
}
extern "C"
void *thread_func(void *arg) {
return reinterpret_cast<void*>(pthread_setspecific(key, arg));
}
static void SpawnThread(uptr iteration) {
destructor_executed = false;
pthread_t tid;
ASSERT_EQ(0, pthread_create(&tid, 0, &thread_func,
reinterpret_cast<void *>(iteration)));
void *retval;
ASSERT_EQ(0, pthread_join(tid, &retval));
ASSERT_EQ(0, retval);
}
TEST(SanitizerCommon, PthreadDestructorIterations) {
ASSERT_EQ(0, pthread_key_create(&key, &destructor));
SpawnThread(GetPthreadDestructorIterations());
EXPECT_TRUE(destructor_executed);
SpawnThread(GetPthreadDestructorIterations() + 1);
#if SANITIZER_SOLARIS
// Solaris continues calling destructors beyond PTHREAD_DESTRUCTOR_ITERATIONS.
EXPECT_TRUE(destructor_executed);
#else
EXPECT_FALSE(destructor_executed);
#endif
ASSERT_EQ(0, pthread_key_delete(key));
}
TEST(SanitizerCommon, IsAccessibleMemoryRange) {
const int page_size = GetPageSize();
uptr mem = (uptr)mmap(0, 3 * page_size, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANON, -1, 0);
// Protect the middle page.
mprotect((void *)(mem + page_size), page_size, PROT_NONE);
EXPECT_TRUE(IsAccessibleMemoryRange(mem, page_size - 1));
EXPECT_TRUE(IsAccessibleMemoryRange(mem, page_size));
EXPECT_FALSE(IsAccessibleMemoryRange(mem, page_size + 1));
EXPECT_TRUE(IsAccessibleMemoryRange(mem + page_size - 1, 1));
EXPECT_FALSE(IsAccessibleMemoryRange(mem + page_size - 1, 2));
EXPECT_FALSE(IsAccessibleMemoryRange(mem + 2 * page_size - 1, 1));
EXPECT_TRUE(IsAccessibleMemoryRange(mem + 2 * page_size, page_size));
EXPECT_FALSE(IsAccessibleMemoryRange(mem, 3 * page_size));
EXPECT_FALSE(IsAccessibleMemoryRange(0x0, 2));
}
} // namespace __sanitizer
#endif // SANITIZER_POSIX