Alexey Samsonov 1f242d6a77 [LSan] Add "use_ld_allocations" flag to disable old way of DTLS handling.
This flag allows to disable old way of determining dynamic TLS by
filtering out allocations from dynamic linker. This will be eventually
superseded by __tls_get_addr interceptor (see r257785), after we:
1) Test it in several supported environments
2) Deal with existing problems (currently we can't find a pointer to
  DTV which is calloc()-ed in pthread_create).

llvm-svn: 257789
2016-01-14 19:16:05 +00:00

51 lines
1.7 KiB
C++

// Test that dynamically allocated TLS space is included in the root set.
// RUN: LSAN_BASE="report_objects=1:use_stacks=0:use_registers=0:use_ld_allocations=0"
// RUN: %clangxx %s -DBUILD_DSO -fPIC -shared -o %t-so.so
// RUN: %clangxx_lsan %s -o %t
// RUN: LSAN_OPTIONS=$LSAN_BASE:"use_tls=0" not %run %t 2>&1 | FileCheck %s
// RUN: LSAN_OPTIONS=$LSAN_BASE:"use_tls=1" %run %t 2>&1
// RUN: LSAN_OPTIONS="" %run %t 2>&1
#ifndef BUILD_DSO
#include <assert.h>
#include <dlfcn.h>
#include <stdio.h>
#include <stdlib.h>
#include <string>
int main(int argc, char *argv[]) {
std::string path = std::string(argv[0]) + "-so.so";
void *handle = dlopen(path.c_str(), RTLD_LAZY);
assert(handle != 0);
typedef void **(* store_t)(void *p);
store_t StoreToTLS = (store_t)dlsym(handle, "StoreToTLS");
assert(dlerror() == 0);
void *p = malloc(1337);
// If we don't know about dynamic TLS, we will return a false leak above.
void **p_in_tls = StoreToTLS(p);
assert(*p_in_tls == p);
fprintf(stderr, "Test alloc: %p.\n", p);
return 0;
}
// CHECK: Test alloc: [[ADDR:.*]].
// CHECK: LeakSanitizer: detected memory leaks
// CHECK: [[ADDR]] (1337 bytes)
// CHECK: SUMMARY: {{(Leak|Address)}}Sanitizer:
#else // BUILD_DSO
// A loadable module with a large thread local section, which would require
// allocation of a new TLS storage chunk when loaded with dlopen(). We use it
// to test the reachability of such chunks in LSan tests.
// This must be large enough that it doesn't fit into preallocated static TLS
// space (see STATIC_TLS_SURPLUS in glibc).
__thread void *huge_thread_local_array[(1 << 20) / sizeof(void *)]; // NOLINT
extern "C" void **StoreToTLS(void *p) {
huge_thread_local_array[0] = p;
return &huge_thread_local_array[0];
}
#endif // BUILD_DSO