summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEvgeniy Stepanov <eugeni.stepanov@gmail.com>2015-06-29 20:28:55 +0000
committerEvgeniy Stepanov <eugeni.stepanov@gmail.com>2015-06-29 20:28:55 +0000
commita522d7328d0e46cc82e007890ae549241618ef0e (patch)
tree7309748d389fb438a2e9d0f90dc7d71fc61c9994
parent17550a3687af0cf22a9de1fe9de366669de111a3 (diff)
downloadcompiler-rt-a522d7328d0e46cc82e007890ae549241618ef0e.tar.gz
[asan] Fix SanitizerCommon.PthreadDestructorIterations test on Android L.
On Android L, TSD destructors run 8 times instead of 4. Back to 4 times on the current master branch (as well as on K). git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@240992 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/asan/asan_thread.h9
-rw-r--r--lib/lsan/lsan_interceptors.cc2
-rw-r--r--lib/msan/msan_thread.cc2
-rw-r--r--lib/sanitizer_common/sanitizer_common.h29
-rw-r--r--lib/sanitizer_common/sanitizer_linux.cc15
-rw-r--r--lib/sanitizer_common/sanitizer_linux_libcdep.cc2
-rw-r--r--lib/sanitizer_common/tests/sanitizer_posix_test.cc4
-rw-r--r--lib/tsan/rtl/tsan_interceptors.cc2
8 files changed, 37 insertions, 28 deletions
diff --git a/lib/asan/asan_thread.h b/lib/asan/asan_thread.h
index a84c855ac..50acfc42d 100644
--- a/lib/asan/asan_thread.h
+++ b/lib/asan/asan_thread.h
@@ -34,12 +34,9 @@ class AsanThread;
class AsanThreadContext : public ThreadContextBase {
public:
explicit AsanThreadContext(int tid)
- : ThreadContextBase(tid),
- announced(false),
- destructor_iterations(kPthreadDestructorIterations),
- stack_id(0),
- thread(0) {
- }
+ : ThreadContextBase(tid), announced(false),
+ destructor_iterations(GetPthreadDestructorIterations()), stack_id(0),
+ thread(0) {}
bool announced;
u8 destructor_iterations;
u32 stack_id;
diff --git a/lib/lsan/lsan_interceptors.cc b/lib/lsan/lsan_interceptors.cc
index ba2519dcb..61a92154d 100644
--- a/lib/lsan/lsan_interceptors.cc
+++ b/lib/lsan/lsan_interceptors.cc
@@ -208,7 +208,7 @@ extern "C" void *__lsan_thread_start_func(void *arg) {
// Wait until the last iteration to maximize the chance that we are the last
// destructor to run.
if (pthread_setspecific(g_thread_finalize_key,
- (void*)kPthreadDestructorIterations)) {
+ (void*)GetPthreadDestructorIterations())) {
Report("LeakSanitizer: failed to set thread key.\n");
Die();
}
diff --git a/lib/msan/msan_thread.cc b/lib/msan/msan_thread.cc
index e15a247c6..0ba499350 100644
--- a/lib/msan/msan_thread.cc
+++ b/lib/msan/msan_thread.cc
@@ -14,7 +14,7 @@ MsanThread *MsanThread::Create(thread_callback_t start_routine,
MsanThread *thread = (MsanThread*)MmapOrDie(size, __func__);
thread->start_routine_ = start_routine;
thread->arg_ = arg;
- thread->destructor_iterations_ = kPthreadDestructorIterations;
+ thread->destructor_iterations_ = GetPthreadDestructorIterations();
return thread;
}
diff --git a/lib/sanitizer_common/sanitizer_common.h b/lib/sanitizer_common/sanitizer_common.h
index e697eb535..7ddedccb7 100644
--- a/lib/sanitizer_common/sanitizer_common.h
+++ b/lib/sanitizer_common/sanitizer_common.h
@@ -613,31 +613,42 @@ typedef bool (*string_predicate_t)(const char *);
uptr GetListOfModules(LoadedModule *modules, uptr max_modules,
string_predicate_t filter);
-#if SANITIZER_POSIX
-const uptr kPthreadDestructorIterations = 4;
-#else
-// Unused on Windows.
-const uptr kPthreadDestructorIterations = 0;
-#endif
-
// Callback type for iterating over a set of memory ranges.
typedef void (*RangeIteratorCallback)(uptr begin, uptr end, void *arg);
+enum AndroidApiLevel {
+ ANDROID_NOT_ANDROID = 0,
+ ANDROID_KITKAT = 19,
+ ANDROID_LOLLIPOP_MR1 = 22,
+ ANDROID_POST_LOLLIPOP = 23
+};
+
#if SANITIZER_ANDROID
// Initialize Android logging. Any writes before this are silently lost.
void AndroidLogInit();
void AndroidLogWrite(const char *buffer);
void GetExtraActivationFlags(char *buf, uptr size);
void SanitizerInitializeUnwinder();
-u32 AndroidGetApiLevel();
+AndroidApiLevel AndroidGetApiLevel();
#else
INLINE void AndroidLogInit() {}
INLINE void AndroidLogWrite(const char *buffer_unused) {}
INLINE void GetExtraActivationFlags(char *buf, uptr size) { *buf = '\0'; }
INLINE void SanitizerInitializeUnwinder() {}
-INLINE u32 AndroidGetApiLevel() { return 0; }
+INLINE AndroidApiLevel AndroidGetApiLevel() { return ANDROID_NOT_ANDROID; }
#endif
+INLINE uptr GetPthreadDestructorIterations() {
+#if SANITIZER_ANDROID
+ return (AndroidGetApiLevel() == ANDROID_LOLLIPOP_MR1) ? 8 : 4;
+#elif SANITIZER_POSIX
+ return 4;
+#else
+// Unused on Windows.
+ return 0;
+#endif
+}
+
void *internal_start_thread(void(*func)(void*), void *arg);
void internal_join_thread(void *th);
void MaybeStartBackgroudThread();
diff --git a/lib/sanitizer_common/sanitizer_linux.cc b/lib/sanitizer_common/sanitizer_linux.cc
index bc2eef25c..7141bcd39 100644
--- a/lib/sanitizer_common/sanitizer_linux.cc
+++ b/lib/sanitizer_common/sanitizer_linux.cc
@@ -955,7 +955,7 @@ extern "C" __attribute__((weak)) int dl_iterate_phdr(
static int dl_iterate_phdr_test_cb(struct dl_phdr_info *info, size_t size,
void *data) {
- // Any name starting with "lib" indicated a bug in L where library base names
+ // Any name starting with "lib" indicates a bug in L where library base names
// are returned instead of paths.
if (info->dlpi_name && info->dlpi_name[0] == 'l' &&
info->dlpi_name[1] == 'i' && info->dlpi_name[2] == 'b') {
@@ -967,20 +967,21 @@ static int dl_iterate_phdr_test_cb(struct dl_phdr_info *info, size_t size,
static atomic_uint32_t android_api_level;
-static u32 AndroidDetectApiLevel() {
+static AndroidApiLevel AndroidDetectApiLevel() {
if (!&dl_iterate_phdr)
- return 19; // K or lower
+ return ANDROID_KITKAT; // K or lower
bool base_name_seen = false;
dl_iterate_phdr(dl_iterate_phdr_test_cb, &base_name_seen);
if (base_name_seen)
- return 22; // L MR1
- return 23; // post-L
+ return ANDROID_LOLLIPOP_MR1; // L MR1
+ return ANDROID_POST_LOLLIPOP; // post-L
// Plain L (API level 21) is completely broken wrt ASan and not very
// interesting to detect.
}
-u32 AndroidGetApiLevel() {
- u32 level = atomic_load(&android_api_level, memory_order_relaxed);
+AndroidApiLevel AndroidGetApiLevel() {
+ AndroidApiLevel level =
+ (AndroidApiLevel)atomic_load(&android_api_level, memory_order_relaxed);
if (level) return level;
level = AndroidDetectApiLevel();
atomic_store(&android_api_level, level, memory_order_relaxed);
diff --git a/lib/sanitizer_common/sanitizer_linux_libcdep.cc b/lib/sanitizer_common/sanitizer_linux_libcdep.cc
index 04ecbb81e..39eb1d216 100644
--- a/lib/sanitizer_common/sanitizer_linux_libcdep.cc
+++ b/lib/sanitizer_common/sanitizer_linux_libcdep.cc
@@ -460,7 +460,7 @@ uptr GetListOfModules(LoadedModule *modules, uptr max_modules,
// Fall back to /proc/maps if dl_iterate_phdr is unavailable or broken.
// The runtime check allows the same library to work with
// both K and L (and future) Android releases.
- if (api_level <= 22) { // L or earlier
+ if (api_level <= ANDROID_LOLLIPOP_MR1) { // L or earlier
MemoryMappingLayout memory_mapping(false);
return memory_mapping.DumpListOfModules(modules, max_modules, filter);
}
diff --git a/lib/sanitizer_common/tests/sanitizer_posix_test.cc b/lib/sanitizer_common/tests/sanitizer_posix_test.cc
index 56ce41614..03ca449d3 100644
--- a/lib/sanitizer_common/tests/sanitizer_posix_test.cc
+++ b/lib/sanitizer_common/tests/sanitizer_posix_test.cc
@@ -52,9 +52,9 @@ static void SpawnThread(uptr iteration) {
TEST(SanitizerCommon, PthreadDestructorIterations) {
ASSERT_EQ(0, pthread_key_create(&key, &destructor));
- SpawnThread(kPthreadDestructorIterations);
+ SpawnThread(GetPthreadDestructorIterations());
EXPECT_TRUE(destructor_executed);
- SpawnThread(kPthreadDestructorIterations + 1);
+ SpawnThread(GetPthreadDestructorIterations() + 1);
EXPECT_FALSE(destructor_executed);
}
diff --git a/lib/tsan/rtl/tsan_interceptors.cc b/lib/tsan/rtl/tsan_interceptors.cc
index a759595c0..d3bef355d 100644
--- a/lib/tsan/rtl/tsan_interceptors.cc
+++ b/lib/tsan/rtl/tsan_interceptors.cc
@@ -826,7 +826,7 @@ extern "C" void *__tsan_thread_start_func(void *arg) {
ScopedIgnoreInterceptors ignore;
ThreadIgnoreBegin(thr, 0);
if (pthread_setspecific(g_thread_finalize_key,
- (void *)kPthreadDestructorIterations)) {
+ (void *)GetPthreadDestructorIterations())) {
Printf("ThreadSanitizer: failed to set thread key\n");
Die();
}