diff options
author | Sergey Matveev <earthdok@google.com> | 2013-11-25 14:25:36 +0000 |
---|---|---|
committer | Sergey Matveev <earthdok@google.com> | 2013-11-25 14:25:36 +0000 |
commit | 94a67a923d871298d4e5d8de64e82b83122c9dd2 (patch) | |
tree | 2969e6b95f0b562750a2f69cdb50c42f82fe7870 /lib/lsan/lsan_interceptors.cc | |
parent | dd83744f358a1374c826b27be0b367f6ebbab4f6 (diff) |
[lsan] Unbreak standalone LSan's initialization by making it more like ASan's.
No longer allow interceptors to be called during initialization, use the preinit
array (instead of initializing at the first call to an intercepted function) and
adopt the calloc() hack from ASan.
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@195642 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/lsan/lsan_interceptors.cc')
-rw-r--r-- | lib/lsan/lsan_interceptors.cc | 43 |
1 files changed, 30 insertions, 13 deletions
diff --git a/lib/lsan/lsan_interceptors.cc b/lib/lsan/lsan_interceptors.cc index faf2a204b..400230b88 100644 --- a/lib/lsan/lsan_interceptors.cc +++ b/lib/lsan/lsan_interceptors.cc @@ -49,6 +49,12 @@ int pthread_setspecific(unsigned key, const void *v); GET_CURRENT_FRAME(), stack_top, stack_bottom, fast); \ } +#define ENSURE_LSAN_INITED do { \ + CHECK(!lsan_init_is_running); \ + if (!lsan_inited) \ + __lsan_init(); \ +} while (0) + ///// Malloc/free interceptors. ///// const bool kAlwaysClearMemory = true; @@ -58,38 +64,49 @@ namespace std { } INTERCEPTOR(void*, malloc, uptr size) { - Init(); + ENSURE_LSAN_INITED; GET_STACK_TRACE; return Allocate(stack, size, 1, kAlwaysClearMemory); } INTERCEPTOR(void, free, void *p) { - Init(); + ENSURE_LSAN_INITED; Deallocate(p); } INTERCEPTOR(void*, calloc, uptr nmemb, uptr size) { + if (lsan_init_is_running) { + // Hack: dlsym calls calloc before REAL(calloc) is retrieved from dlsym. + const uptr kCallocPoolSize = 1024; + static uptr calloc_memory_for_dlsym[kCallocPoolSize]; + static uptr allocated; + uptr size_in_words = ((nmemb * size) + kWordSize - 1) / kWordSize; + void *mem = (void*)&calloc_memory_for_dlsym[allocated]; + allocated += size_in_words; + CHECK(allocated < kCallocPoolSize); + return mem; + } if (CallocShouldReturnNullDueToOverflow(size, nmemb)) return 0; - Init(); + ENSURE_LSAN_INITED; GET_STACK_TRACE; size *= nmemb; return Allocate(stack, size, 1, true); } INTERCEPTOR(void*, realloc, void *q, uptr size) { - Init(); + ENSURE_LSAN_INITED; GET_STACK_TRACE; return Reallocate(stack, q, size, 1); } INTERCEPTOR(void*, memalign, uptr alignment, uptr size) { - Init(); + ENSURE_LSAN_INITED; GET_STACK_TRACE; return Allocate(stack, size, alignment, kAlwaysClearMemory); } INTERCEPTOR(int, posix_memalign, void **memptr, uptr alignment, uptr size) { - Init(); + ENSURE_LSAN_INITED; GET_STACK_TRACE; *memptr = Allocate(stack, size, alignment, kAlwaysClearMemory); // FIXME: Return ENOMEM if user requested more than max alloc size. @@ -97,7 +114,7 @@ INTERCEPTOR(int, posix_memalign, void **memptr, uptr alignment, uptr size) { } INTERCEPTOR(void*, valloc, uptr size) { - Init(); + ENSURE_LSAN_INITED; GET_STACK_TRACE; if (size == 0) size = GetPageSizeCached(); @@ -105,7 +122,7 @@ INTERCEPTOR(void*, valloc, uptr size) { } INTERCEPTOR(uptr, malloc_usable_size, void *ptr) { - Init(); + ENSURE_LSAN_INITED; return GetMallocUsableSize(ptr); } @@ -124,7 +141,7 @@ INTERCEPTOR(int, mallopt, int cmd, int value) { } INTERCEPTOR(void*, pvalloc, uptr size) { - Init(); + ENSURE_LSAN_INITED; GET_STACK_TRACE; uptr PageSize = GetPageSizeCached(); size = RoundUpTo(size, PageSize); @@ -138,7 +155,7 @@ INTERCEPTOR(void*, pvalloc, uptr size) { INTERCEPTOR(void, cfree, void *p) ALIAS("free"); #define OPERATOR_NEW_BODY \ - Init(); \ + ENSURE_LSAN_INITED; \ GET_STACK_TRACE; \ return Allocate(stack, size, 1, kAlwaysClearMemory); @@ -152,7 +169,7 @@ INTERCEPTOR_ATTRIBUTE void *operator new[](uptr size, std::nothrow_t const&) { OPERATOR_NEW_BODY; } #define OPERATOR_DELETE_BODY \ - Init(); \ + ENSURE_LSAN_INITED; \ Deallocate(ptr); INTERCEPTOR_ATTRIBUTE @@ -214,7 +231,7 @@ extern "C" void *__lsan_thread_start_func(void *arg) { INTERCEPTOR(int, pthread_create, void *th, void *attr, void *(*callback)(void *), void *param) { - Init(); + ENSURE_LSAN_INITED; EnsureMainThreadIDIsCorrect(); __sanitizer_pthread_attr_t myattr; if (attr == 0) { @@ -242,7 +259,7 @@ INTERCEPTOR(int, pthread_create, void *th, void *attr, } INTERCEPTOR(int, pthread_join, void *th, void **ret) { - Init(); + ENSURE_LSAN_INITED; int tid = ThreadTid((uptr)th); int res = REAL(pthread_join)(th, ret); if (res == 0) |