[lsan] Convert the remaining LSan tests to output tests.
llvm-svn: 182839
This commit is contained in:
parent
f28217ad0e
commit
e615432313
|
@ -0,0 +1,12 @@
|
|||
// 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];
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
// Test that LargeMmapAllocator's chunks aren't reachable via some internal data structure.
|
||||
// RUN: LSAN_BASE="report_blocks=1:use_stacks=0:use_registers=0"
|
||||
// RUN: %clangxx_lsan %s -o %t
|
||||
// RUN: LSAN_OPTIONS=$LSAN_BASE %t 2>&1 | FileCheck %s
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
int main() {
|
||||
// maxsize in primary allocator is always less than this (1 << 25).
|
||||
void *large_alloc = malloc(33554432);
|
||||
fprintf(stderr, "Test alloc: %p.\n", large_alloc);
|
||||
return 0;
|
||||
}
|
||||
// CHECK: Test alloc: [[ADDR:.*]].
|
||||
// CHECK: LeakSanitizer: detected memory leaks
|
||||
// CHECK: Directly leaked 33554432 byte block at [[ADDR]]
|
||||
// CHECK: SUMMARY: LeakSanitizer:
|
|
@ -0,0 +1,42 @@
|
|||
// Test that out-of-scope local variables are ignored by LSan.
|
||||
// RUN: LSAN_BASE="report_blocks=1:use_registers=0:use_stacks=1"
|
||||
// RUN: %clangxx_lsan %s -o %t
|
||||
// RUN: LSAN_OPTIONS=$LSAN_BASE %t 2>&1 | FileCheck %s
|
||||
// RUN: LSAN_OPTIONS=$LSAN_BASE":exitcode=0" %t 2>&1 | FileCheck --check-prefix=CHECK-sanity %s
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
void **pp;
|
||||
|
||||
// Put pointer far enough on the stack that LSan has space to run in without
|
||||
// overwriting it.
|
||||
// Hopefully the argument p will be passed on a register, saving us from false
|
||||
// negatives.
|
||||
__attribute__((noinline))
|
||||
void *PutPointerOnStaleStack(void *p) {
|
||||
void *locals[2048];
|
||||
locals[0] = p;
|
||||
pp = &locals[0];
|
||||
fprintf(stderr, "Test alloc: %p.\n", locals[0]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main() {
|
||||
PutPointerOnStaleStack(malloc(1337));
|
||||
return 0;
|
||||
}
|
||||
|
||||
// This must run after LSan, to ensure LSan didn't overwrite the pointer before
|
||||
// it had a chance to see it. If LSan is invoked with atexit(), this works.
|
||||
// Otherwise, we need a different method.
|
||||
__attribute__((destructor))
|
||||
void ConfirmPointerHasSurvived() {
|
||||
fprintf(stderr, "Value after LSan: %p.\n", *pp);
|
||||
}
|
||||
// CHECK: Test alloc: [[ADDR:.*]].
|
||||
// CHECK-sanity: Test alloc: [[ADDR:.*]].
|
||||
// CHECK: LeakSanitizer: detected memory leaks
|
||||
// CHECK: Directly leaked 1337 byte block at [[ADDR]]
|
||||
// CHECK: SUMMARY: LeakSanitizer:
|
||||
// CHECK-sanity: Value after LSan: [[ADDR]].
|
|
@ -0,0 +1,21 @@
|
|||
// Test that uninitialized globals are included in the root set.
|
||||
// RUN: LSAN_BASE="report_blocks=1:use_stacks=0:use_registers=0"
|
||||
// RUN: %clangxx_lsan %s -o %t
|
||||
// RUN: LSAN_OPTIONS=$LSAN_BASE:"use_globals=0" %t 2>&1 | FileCheck %s
|
||||
// RUN: LSAN_OPTIONS=$LSAN_BASE:"use_globals=1" %t 2>&1
|
||||
// RUN: LSAN_OPTIONS="" %t 2>&1
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
void *bss_var;
|
||||
|
||||
int main() {
|
||||
bss_var = malloc(1337);
|
||||
fprintf(stderr, "Test alloc: %p.\n", bss_var);
|
||||
return 0;
|
||||
}
|
||||
// CHECK: Test alloc: [[ADDR:.*]].
|
||||
// CHECK: LeakSanitizer: detected memory leaks
|
||||
// CHECK: Directly leaked 1337 byte block at [[ADDR]]
|
||||
// CHECK: SUMMARY: LeakSanitizer:
|
|
@ -0,0 +1,51 @@
|
|||
// Test that registers of running threads are included in the root set.
|
||||
// RUN: LSAN_BASE="report_blocks=1:use_stacks=0"
|
||||
// RUN: %clangxx_lsan -pthread %s -o %t
|
||||
// RUN: LSAN_OPTIONS=$LSAN_BASE:"use_registers=0" %t 2>&1 | FileCheck %s
|
||||
// RUN: LSAN_OPTIONS=$LSAN_BASE:"use_registers=1" %t 2>&1
|
||||
// RUN: LSAN_OPTIONS="" %t 2>&1
|
||||
|
||||
#include <assert.h>
|
||||
#include <pthread.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
extern "C"
|
||||
void *registers_thread_func(void *arg) {
|
||||
int *sync = reinterpret_cast<int *>(arg);
|
||||
void *p = malloc(1337);
|
||||
// To store the pointer, choose a register which is unlikely to be reused by
|
||||
// a function call.
|
||||
#if defined(__i386__)
|
||||
asm ( "mov %0, %%esi"
|
||||
:
|
||||
: "r" (p)
|
||||
);
|
||||
#elif defined(__x86_64__)
|
||||
asm ( "mov %0, %%r15"
|
||||
:
|
||||
: "r" (p)
|
||||
);
|
||||
#else
|
||||
#error "Test is not supported on this architecture."
|
||||
#endif
|
||||
fprintf(stderr, "Test alloc: %p.\n", p);
|
||||
fflush(stderr);
|
||||
__sync_fetch_and_xor(sync, 1);
|
||||
while (true)
|
||||
pthread_yield();
|
||||
}
|
||||
|
||||
int main() {
|
||||
int sync = 0;
|
||||
pthread_t thread_id;
|
||||
int res = pthread_create(&thread_id, 0, registers_thread_func, &sync);
|
||||
assert(res == 0);
|
||||
while (!__sync_fetch_and_xor(&sync, 0))
|
||||
pthread_yield();
|
||||
return 0;
|
||||
}
|
||||
// CHECK: Test alloc: [[ADDR:.*]].
|
||||
// CHECK: LeakSanitizer: detected memory leaks
|
||||
// CHECK: Directly leaked 1337 byte block at [[ADDR]]
|
||||
// CHECK: SUMMARY: LeakSanitizer:
|
|
@ -0,0 +1,20 @@
|
|||
// Test that stack of main thread is included in the root set.
|
||||
// RUN: LSAN_BASE="report_blocks=1:use_registers=0"
|
||||
// RUN: %clangxx_lsan %s -o %t
|
||||
// RUN: LSAN_OPTIONS=$LSAN_BASE:"use_stacks=0" %t 2>&1 | FileCheck %s
|
||||
// RUN: LSAN_OPTIONS=$LSAN_BASE:"use_stacks=1" %t 2>&1
|
||||
// RUN: LSAN_OPTIONS="" %t 2>&1
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
int main() {
|
||||
void *stack_var = malloc(1337);
|
||||
fprintf(stderr, "Test alloc: %p.\n", stack_var);
|
||||
// Do not return from main to prevent the pointer from going out of scope.
|
||||
exit(0);
|
||||
}
|
||||
// CHECK: Test alloc: [[ADDR:.*]].
|
||||
// CHECK: LeakSanitizer: detected memory leaks
|
||||
// CHECK: Directly leaked 1337 byte block at [[ADDR]]
|
||||
// CHECK: SUMMARY: LeakSanitizer:
|
|
@ -0,0 +1,36 @@
|
|||
// Test that stacks of non-main threads are included in the root set.
|
||||
// RUN: LSAN_BASE="report_blocks=1:use_registers=0"
|
||||
// RUN: %clangxx_lsan -pthread %s -o %t
|
||||
// RUN: LSAN_OPTIONS=$LSAN_BASE:"use_stacks=0" %t 2>&1 | FileCheck %s
|
||||
// RUN: LSAN_OPTIONS=$LSAN_BASE:"use_stacks=1" %t 2>&1
|
||||
// RUN: LSAN_OPTIONS="" %t 2>&1
|
||||
|
||||
#include <assert.h>
|
||||
#include <pthread.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
extern "C"
|
||||
void *stacks_thread_func(void *arg) {
|
||||
int *sync = reinterpret_cast<int *>(arg);
|
||||
void *p = malloc(1337);
|
||||
fprintf(stderr, "Test alloc: %p.\n", p);
|
||||
fflush(stderr);
|
||||
__sync_fetch_and_xor(sync, 1);
|
||||
while (true)
|
||||
pthread_yield();
|
||||
}
|
||||
|
||||
int main() {
|
||||
int sync = 0;
|
||||
pthread_t thread_id;
|
||||
int res = pthread_create(&thread_id, 0, stacks_thread_func, &sync);
|
||||
assert(res == 0);
|
||||
while (!__sync_fetch_and_xor(&sync, 0))
|
||||
pthread_yield();
|
||||
return 0;
|
||||
}
|
||||
// CHECK: Test alloc: [[ADDR:.*]].
|
||||
// CHECK: LeakSanitizer: detected memory leaks
|
||||
// CHECK: Directly leaked 1337 byte block at [[ADDR]]
|
||||
// CHECK: SUMMARY: LeakSanitizer:
|
|
@ -0,0 +1,33 @@
|
|||
// Test that dynamically allocated TLS space is included in the root set.
|
||||
// RUN: LSAN_BASE="report_blocks=1:use_stacks=0:use_registers=0"
|
||||
// RUN: %clangxx %p/SharedLibs/huge_tls_lib_so.cc -fPIC -shared -o %t-so.so
|
||||
// RUN: %clangxx_lsan %s -o %t
|
||||
// RUN: LSAN_OPTIONS=$LSAN_BASE:"use_tls=0" %t 2>&1 | FileCheck %s
|
||||
// RUN: LSAN_OPTIONS=$LSAN_BASE:"use_tls=1" %t 2>&1
|
||||
// RUN: LSAN_OPTIONS="" %t 2>&1
|
||||
|
||||
#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);
|
||||
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: leaked 1337 byte block at [[ADDR]]
|
||||
// CHECK: SUMMARY: LeakSanitizer:
|
|
@ -0,0 +1,37 @@
|
|||
// Test that dynamically allocated thread-specific storage is included in the root set.
|
||||
// RUN: LSAN_BASE="report_blocks=1:use_stacks=0:use_registers=0"
|
||||
// RUN: %clangxx_lsan %s -o %t
|
||||
// RUN: LSAN_OPTIONS=$LSAN_BASE:"use_tls=0" %t 2>&1 | FileCheck %s
|
||||
// RUN: LSAN_OPTIONS=$LSAN_BASE:"use_tls=1" %t 2>&1
|
||||
// RUN: LSAN_OPTIONS="" %t 2>&1
|
||||
|
||||
#include <assert.h>
|
||||
#include <pthread.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
// From glibc: this many keys are stored in the thread descriptor directly.
|
||||
const unsigned PTHREAD_KEY_2NDLEVEL_SIZE = 32;
|
||||
|
||||
int main() {
|
||||
static const unsigned kDummyKeysCount = PTHREAD_KEY_2NDLEVEL_SIZE;
|
||||
int res;
|
||||
pthread_key_t dummy_keys[kDummyKeysCount];
|
||||
for (unsigned i = 0; i < kDummyKeysCount; i++) {
|
||||
res = pthread_key_create(&dummy_keys[i], NULL);
|
||||
assert(res == 0);
|
||||
}
|
||||
pthread_key_t key;
|
||||
res = pthread_key_create(&key, NULL);
|
||||
assert(key >= PTHREAD_KEY_2NDLEVEL_SIZE);
|
||||
assert(res == 0);
|
||||
void *p = malloc(1337);
|
||||
res = pthread_setspecific(key, p);
|
||||
assert(res == 0);
|
||||
fprintf(stderr, "Test alloc: %p.\n", p);
|
||||
return 0;
|
||||
}
|
||||
// CHECK: Test alloc: [[ADDR:.*]].
|
||||
// CHECK: LeakSanitizer: detected memory leaks
|
||||
// CHECK: leaked 1337 byte block at [[ADDR]]
|
||||
// CHECK: SUMMARY: LeakSanitizer:
|
|
@ -0,0 +1,31 @@
|
|||
// Test that statically allocated thread-specific storage is included in the root set.
|
||||
// RUN: LSAN_BASE="report_blocks=1:use_stacks=0:use_registers=0"
|
||||
// RUN: %clangxx_lsan %s -o %t
|
||||
// RUN: LSAN_OPTIONS=$LSAN_BASE:"use_tls=0" %t 2>&1 | FileCheck %s
|
||||
// RUN: LSAN_OPTIONS=$LSAN_BASE:"use_tls=1" %t 2>&1
|
||||
// RUN: LSAN_OPTIONS="" %t 2>&1
|
||||
|
||||
#include <assert.h>
|
||||
#include <pthread.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
// From glibc: this many keys are stored in the thread descriptor directly.
|
||||
const unsigned PTHREAD_KEY_2NDLEVEL_SIZE = 32;
|
||||
|
||||
int main() {
|
||||
pthread_key_t key;
|
||||
int res;
|
||||
res = pthread_key_create(&key, NULL);
|
||||
assert(res == 0);
|
||||
assert(key < PTHREAD_KEY_2NDLEVEL_SIZE);
|
||||
void *p = malloc(1337);
|
||||
res = pthread_setspecific(key, p);
|
||||
assert(res == 0);
|
||||
fprintf(stderr, "Test alloc: %p.\n", p);
|
||||
return 0;
|
||||
}
|
||||
// CHECK: Test alloc: [[ADDR:.*]].
|
||||
// CHECK: LeakSanitizer: detected memory leaks
|
||||
// CHECK: Directly leaked 1337 byte block at [[ADDR]]
|
||||
// CHECK: SUMMARY: LeakSanitizer:
|
|
@ -0,0 +1,21 @@
|
|||
// Test that statically allocated TLS space is included in the root set.
|
||||
// RUN: LSAN_BASE="report_blocks=1:use_stacks=0:use_registers=0"
|
||||
// RUN: %clangxx_lsan %s -o %t
|
||||
// RUN: LSAN_OPTIONS=$LSAN_BASE:"use_tls=0" %t 2>&1 | FileCheck %s
|
||||
// RUN: LSAN_OPTIONS=$LSAN_BASE:"use_tls=1" %t 2>&1
|
||||
// RUN: LSAN_OPTIONS="" %t 2>&1
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
__thread void *tls_var;
|
||||
|
||||
int main() {
|
||||
tls_var = malloc(1337);
|
||||
fprintf(stderr, "Test alloc: %p.\n", tls_var);
|
||||
return 0;
|
||||
}
|
||||
// CHECK: Test alloc: [[ADDR:.*]].
|
||||
// CHECK: LeakSanitizer: detected memory leaks
|
||||
// CHECK: Directly leaked 1337 byte block at [[ADDR]]
|
||||
// CHECK: SUMMARY: LeakSanitizer:
|
|
@ -0,0 +1,23 @@
|
|||
// Test that unaligned pointers are detected correctly.
|
||||
// RUN: LSAN_BASE="report_blocks=1:use_stacks=0:use_registers=0"
|
||||
// RUN: %clangxx_lsan %s -o %t
|
||||
// RUN: LSAN_OPTIONS=$LSAN_BASE:"use_unaligned=0" %t 2>&1 | FileCheck %s
|
||||
// RUN: LSAN_OPTIONS=$LSAN_BASE:"use_unaligned=1" %t 2>&1
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
void *arr[2];
|
||||
|
||||
int main() {
|
||||
void *p = malloc(1337);
|
||||
fprintf(stderr, "Test alloc: %p.\n", p);
|
||||
char *char_arr = (char *)arr;
|
||||
memcpy(char_arr + 1, &p, sizeof(p));
|
||||
return 0;
|
||||
}
|
||||
// CHECK: Test alloc: [[ADDR:.*]].
|
||||
// CHECK: LeakSanitizer: detected memory leaks
|
||||
// CHECK: Directly leaked 1337 byte block at [[ADDR]]
|
||||
// CHECK: SUMMARY: LeakSanitizer:
|
|
@ -80,7 +80,8 @@ ${CPPLINT} --filter=${MSAN_RTL_LINT_FILTER} ${MSAN_RTL}/*.{cc,h}
|
|||
LSAN_RTL=${COMPILER_RT}/lib/lsan
|
||||
${CPPLINT} --filter=${LSAN_RTL_LINT_FILTER} ${LSAN_RTL}/*.{cc,h}
|
||||
${CPPLINT} --filter=${LSAN_RTL_LINT_FILTER} ${LSAN_RTL}/tests/*.{cc,h}
|
||||
${CPPLINT} --filter=${LSAN_LIT_TEST_LINT_FILTER} ${LSAN_RTL}/lit_tests/*.{cc,h}
|
||||
${CPPLINT} --filter=${LSAN_LIT_TEST_LINT_FILTER} ${LSAN_RTL}/lit_tests/*.{cc,h} \
|
||||
${LSAN_RTL}/lit_tests/*/*.cc
|
||||
|
||||
set +e
|
||||
|
||||
|
|
Loading…
Reference in New Issue