diff options
author | Evgeniy Stepanov <eugeni.stepanov@gmail.com> | 2015-06-29 20:28:55 +0000 |
---|---|---|
committer | Evgeniy Stepanov <eugeni.stepanov@gmail.com> | 2015-06-29 20:28:55 +0000 |
commit | a522d7328d0e46cc82e007890ae549241618ef0e (patch) | |
tree | 7309748d389fb438a2e9d0f90dc7d71fc61c9994 | |
parent | 17550a3687af0cf22a9de1fe9de366669de111a3 (diff) | |
download | compiler-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.h | 9 | ||||
-rw-r--r-- | lib/lsan/lsan_interceptors.cc | 2 | ||||
-rw-r--r-- | lib/msan/msan_thread.cc | 2 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_common.h | 29 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_linux.cc | 15 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_linux_libcdep.cc | 2 | ||||
-rw-r--r-- | lib/sanitizer_common/tests/sanitizer_posix_test.cc | 4 | ||||
-rw-r--r-- | lib/tsan/rtl/tsan_interceptors.cc | 2 |
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(); } |