Revert "Implement tls scanning for darwin LSan"

This reverts r303262, due to TSan buildbot breakages.

llvm-svn: 303266
This commit is contained in:
Francis Ricci 2017-05-17 15:25:41 +00:00
parent 1f64bf6c69
commit 3b57da0c73
5 changed files with 22 additions and 134 deletions

View File

@ -265,21 +265,19 @@ static void ProcessThreads(SuspendedThreadsList const &suspended_threads,
}
if (flags()->use_tls) {
if (tls_begin) {
LOG_THREADS("TLS at %p-%p.\n", tls_begin, tls_end);
// If the tls and cache ranges don't overlap, scan full tls range,
// otherwise, only scan the non-overlapping portions
if (cache_begin == cache_end || tls_end < cache_begin ||
tls_end > cache_end) {
ScanRangeForPointers(tls_begin, tls_end, frontier, "TLS", kReachable);
} else {
if (tls_begin < cache_begin)
ScanRangeForPointers(tls_begin, cache_begin, frontier, "TLS",
kReachable);
if (tls_end > cache_end)
ScanRangeForPointers(cache_end, tls_end, frontier, "TLS",
kReachable);
}
LOG_THREADS("TLS at %p-%p.\n", tls_begin, tls_end);
if (cache_begin == cache_end) {
ScanRangeForPointers(tls_begin, tls_end, frontier, "TLS", kReachable);
} else {
// Because LSan should not be loaded with dlopen(), we can assume
// that allocator cache will be part of static TLS image.
CHECK_LE(tls_begin, cache_begin);
CHECK_GE(tls_end, cache_end);
if (tls_begin < cache_begin)
ScanRangeForPointers(tls_begin, cache_begin, frontier, "TLS",
kReachable);
if (tls_end > cache_end)
ScanRangeForPointers(cache_end, tls_end, frontier, "TLS", kReachable);
}
if (dtls && !DTLSInDestruction(dtls)) {
for (uptr j = 0; j < dtls->dtv_size; ++j) {

View File

@ -91,7 +91,12 @@ LoadedModule *GetLinker() { return nullptr; }
// Required on Linux for initialization of TLS behavior, but should not be
// required on Darwin.
void InitializePlatformSpecificModules() {}
void InitializePlatformSpecificModules() {
if (flags()->use_tls) {
Report("use_tls=1 is not supported on Darwin.\n");
Die();
}
}
// Scans global variables for heap pointers.
void ProcessGlobalRegions(Frontier *frontier) {

View File

@ -30,7 +30,7 @@ LSAN_FLAG(bool, use_globals, true,
"Root set: include global variables (.data and .bss)")
LSAN_FLAG(bool, use_stacks, true, "Root set: include thread stacks")
LSAN_FLAG(bool, use_registers, true, "Root set: include thread registers")
LSAN_FLAG(bool, use_tls, true,
LSAN_FLAG(bool, use_tls, !SANITIZER_MAC,
"Root set: include TLS and thread-specific storage")
LSAN_FLAG(bool, use_root_regions, true,
"Root set: include regions added via __lsan_register_root_region().")

View File

@ -370,27 +370,6 @@ uptr GetTlsSize() {
void InitTlsSize() {
}
uptr TlsBaseAddr() {
uptr segbase = 0;
#if defined(__x86_64__)
asm("movq %%gs:0,%0" : "=r"(segbase));
#elif defined(__i386__)
asm("movl %%gs:0,%0" : "=r"(segbase));
#endif
return segbase;
}
// The size of the tls on darwin does not appear to be well documented,
// however the vm memory map suggests that it is 1024 uptrs in size,
// with a size of 0x2000 bytes on x86_64 and 0x1000 bytes on i386.
uptr TlsSize() {
#if defined(__x86_64__) || defined(__i386__)
return 1024 * sizeof(uptr);
#else
return 0;
#endif
}
void GetThreadStackAndTls(bool main, uptr *stk_addr, uptr *stk_size,
uptr *tls_addr, uptr *tls_size) {
#if !SANITIZER_GO
@ -398,8 +377,8 @@ void GetThreadStackAndTls(bool main, uptr *stk_addr, uptr *stk_size,
GetThreadStackTopAndBottom(main, &stack_top, &stack_bottom);
*stk_addr = stack_bottom;
*stk_size = stack_top - stack_bottom;
*tls_addr = TlsBaseAddr();
*tls_size = TlsSize();
*tls_addr = 0;
*tls_size = 0;
#else
*stk_addr = 0;
*stk_size = 0;

View File

@ -1,94 +0,0 @@
// Test that lsan handles tls correctly for many threads
// RUN: LSAN_BASE="report_objects=1:use_stacks=0:use_registers=0"
// RUN: %clangxx_lsan %s -DUSE_THREAD -o %t-thread
// RUN: %clangxx_lsan %s -DUSE_PTHREAD -o %t-pthread
// RUN: %env_lsan_opts=$LSAN_BASE:"use_tls=0" not %run %t-thread 2>&1 | FileCheck %s
// RUN: %env_lsan_opts=$LSAN_BASE:"use_tls=1" %run %t-thread 2>&1
// RUN: %env_lsan_opts="" %run %t-thread 2>&1
// RUN: %env_lsan_opts=$LSAN_BASE:"use_tls=0" not %run %t-pthread 2>&1 | FileCheck %s
// RUN: %env_lsan_opts=$LSAN_BASE:"use_tls=1" %run %t-pthread 2>&1
// RUN: %env_lsan_opts="" %run %t-pthread 2>&1
#include <assert.h>
#include <limits.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
static const int NUM_THREADS = 10;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
int finished = 0;
#if USE_THREAD
__thread void *ptr1;
__thread void *ptr2;
__thread void *ptr3;
__thread void *ptr4;
__thread void *ptr5;
void alloc() {
ptr1 = malloc(1111);
ptr2 = malloc(2222);
ptr3 = malloc(3333);
ptr4 = malloc(4444);
ptr5 = malloc(5555);
}
#elif USE_PTHREAD
// We won't be able to create the maximum number of keys, due to other users
// of the tls, but we'll use as many keys as we can before failing to create
// a new key.
pthread_key_t keys[PTHREAD_KEYS_MAX];
static const int PTHREAD_KEY_INVALID = 0xffffffff;
void alloc() {
for (int i = 0; i < PTHREAD_KEYS_MAX; ++i) {
void *ptr = malloc(123);
if ((keys[i] == PTHREAD_KEY_INVALID) || pthread_setspecific(keys[i], ptr)) {
free(ptr);
break;
}
}
}
void pthread_destructor(void *arg) {
assert(0 && "pthread destructors shouldn't be called");
}
#endif
void *thread_start(void *arg) {
alloc();
pthread_mutex_lock(&mutex);
finished++;
pthread_mutex_unlock(&mutex);
// don't exit, to intentionally leak tls data
while (1)
sleep(100);
}
int main() {
#if USE_PTHREAD
for (int i = 0; i < PTHREAD_KEYS_MAX; ++i) {
if (pthread_key_create(&keys[i], pthread_destructor)) {
keys[i] = PTHREAD_KEY_INVALID;
break;
}
}
#endif
pthread_t thread[NUM_THREADS];
for (int i = 0; i < NUM_THREADS; ++i) {
assert(0 == pthread_create(&thread[i], 0, thread_start, 0));
}
// spin until all threads have finished
while (finished < NUM_THREADS)
sleep(1);
exit(0);
}
// CHECK: LeakSanitizer: detected memory leaks
// CHECK: SUMMARY: {{(Leak|Address)}}Sanitizer: