forked from OSchip/llvm-project
[sanitizer] Move the PTHREAD_DESTRUCTOR_ITERATIONS constant to sanitizer_linux.h.
Add a test. llvm-svn: 192442
This commit is contained in:
parent
0cd96165f1
commit
dc75cf3368
|
|
@ -192,9 +192,6 @@ struct ThreadParam {
|
||||||
atomic_uintptr_t tid;
|
atomic_uintptr_t tid;
|
||||||
};
|
};
|
||||||
|
|
||||||
// PTHREAD_DESTRUCTOR_ITERATIONS from glibc.
|
|
||||||
const uptr kPthreadDestructorIterations = 4;
|
|
||||||
|
|
||||||
extern "C" void *__lsan_thread_start_func(void *arg) {
|
extern "C" void *__lsan_thread_start_func(void *arg) {
|
||||||
ThreadParam *p = (ThreadParam*)arg;
|
ThreadParam *p = (ThreadParam*)arg;
|
||||||
void* (*callback)(void *arg) = p->callback;
|
void* (*callback)(void *arg) = p->callback;
|
||||||
|
|
|
||||||
|
|
@ -77,6 +77,8 @@ void CacheBinaryName();
|
||||||
// Call cb for each region mapped by map.
|
// Call cb for each region mapped by map.
|
||||||
void ForEachMappedRegion(link_map *map, void (*cb)(const void *, uptr));
|
void ForEachMappedRegion(link_map *map, void (*cb)(const void *, uptr));
|
||||||
|
|
||||||
|
// PTHREAD_DESTRUCTOR_ITERATIONS from glibc.
|
||||||
|
const uptr kPthreadDestructorIterations = 4;
|
||||||
} // namespace __sanitizer
|
} // namespace __sanitizer
|
||||||
|
|
||||||
#endif // SANITIZER_LINUX
|
#endif // SANITIZER_LINUX
|
||||||
|
|
|
||||||
|
|
@ -255,6 +255,42 @@ TEST(SanitizerCommon, LibraryNameIs) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pthread_key_t key;
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
|
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(kPthreadDestructorIterations);
|
||||||
|
EXPECT_TRUE(destructor_executed);
|
||||||
|
SpawnThread(kPthreadDestructorIterations + 1);
|
||||||
|
EXPECT_FALSE(destructor_executed);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace __sanitizer
|
} // namespace __sanitizer
|
||||||
|
|
||||||
#endif // SANITIZER_LINUX
|
#endif // SANITIZER_LINUX
|
||||||
|
|
|
||||||
|
|
@ -853,7 +853,8 @@ extern "C" void *__tsan_thread_start_func(void *arg) {
|
||||||
{
|
{
|
||||||
ThreadState *thr = cur_thread();
|
ThreadState *thr = cur_thread();
|
||||||
ScopedInRtl in_rtl;
|
ScopedInRtl in_rtl;
|
||||||
if (pthread_setspecific(g_thread_finalize_key, (void*)4)) {
|
if (pthread_setspecific(g_thread_finalize_key,
|
||||||
|
(void *)kPthreadDestructorIterations)) {
|
||||||
Printf("ThreadSanitizer: failed to set thread key\n");
|
Printf("ThreadSanitizer: failed to set thread key\n");
|
||||||
Die();
|
Die();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue