diff options
author | kcc <kcc@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-11-23 14:46:25 +0000 |
---|---|---|
committer | kcc <kcc@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-11-23 14:46:25 +0000 |
commit | 0d996a11d9b5be7a52d77016de51910146ceaa90 (patch) | |
tree | a354102cd1c27b09eefe0b04f517d4ecac5bc566 /libsanitizer/asan | |
parent | a46419387192ae39f45cfeca2ec0afe6f872956e (diff) | |
download | gcc-0d996a11d9b5be7a52d77016de51910146ceaa90.tar.gz |
[libsanitizer] merge from upstream r168514
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@193756 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libsanitizer/asan')
-rw-r--r-- | libsanitizer/asan/asan_allocator.cc | 4 | ||||
-rw-r--r-- | libsanitizer/asan/asan_intercepted_functions.h | 6 | ||||
-rw-r--r-- | libsanitizer/asan/asan_interceptors.cc | 49 | ||||
-rw-r--r-- | libsanitizer/asan/asan_internal.h | 1 | ||||
-rw-r--r-- | libsanitizer/asan/asan_linux.cc | 28 | ||||
-rw-r--r-- | libsanitizer/asan/asan_mac.cc | 20 | ||||
-rw-r--r-- | libsanitizer/asan/asan_mac.h | 5 | ||||
-rw-r--r-- | libsanitizer/asan/asan_malloc_mac.cc | 30 | ||||
-rw-r--r-- | libsanitizer/asan/asan_mapping.h | 18 | ||||
-rw-r--r-- | libsanitizer/asan/asan_new_delete.cc | 38 | ||||
-rw-r--r-- | libsanitizer/asan/asan_report.cc | 22 | ||||
-rw-r--r-- | libsanitizer/asan/asan_rtl.cc | 2 | ||||
-rw-r--r-- | libsanitizer/asan/asan_stats.cc | 3 | ||||
-rw-r--r-- | libsanitizer/asan/asan_thread.cc | 13 | ||||
-rw-r--r-- | libsanitizer/asan/asan_thread_registry.cc | 23 | ||||
-rw-r--r-- | libsanitizer/asan/asan_thread_registry.h | 4 | ||||
-rw-r--r-- | libsanitizer/asan/asan_win.cc | 4 |
17 files changed, 191 insertions, 79 deletions
diff --git a/libsanitizer/asan/asan_allocator.cc b/libsanitizer/asan/asan_allocator.cc index 3a92802e972..63ff607f858 100644 --- a/libsanitizer/asan/asan_allocator.cc +++ b/libsanitizer/asan/asan_allocator.cc @@ -56,7 +56,7 @@ static const uptr kMallocSizeClassStepLog = 26; static const uptr kMallocSizeClassStep = 1UL << kMallocSizeClassStepLog; static const uptr kMaxAllowedMallocSize = - (__WORDSIZE == 32) ? 3UL << 30 : 8UL << 30; + (SANITIZER_WORDSIZE == 32) ? 3UL << 30 : 8UL << 30; static inline bool IsAligned(uptr a, uptr alignment) { return (a & (alignment - 1)) == 0; @@ -83,7 +83,7 @@ static inline uptr RoundUpToPowerOfTwo(uptr size) { unsigned long up; // NOLINT #if !defined(_WIN32) || defined(__clang__) - up = __WORDSIZE - 1 - __builtin_clzl(size); + up = SANITIZER_WORDSIZE - 1 - __builtin_clzl(size); #elif defined(_WIN64) _BitScanReverse64(&up, size); #else diff --git a/libsanitizer/asan/asan_intercepted_functions.h b/libsanitizer/asan/asan_intercepted_functions.h index ceb596cd48e..62d1994130f 100644 --- a/libsanitizer/asan/asan_intercepted_functions.h +++ b/libsanitizer/asan/asan_intercepted_functions.h @@ -49,6 +49,12 @@ using __sanitizer::uptr; # define ASAN_INTERCEPT_STRNLEN 0 #endif +#if defined(__linux__) && !defined(ANDROID) +# define ASAN_INTERCEPT_SWAPCONTEXT 1 +#else +# define ASAN_INTERCEPT_SWAPCONTEXT 0 +#endif + #if !defined(ANDROID) && !defined(_WIN32) # define ASAN_INTERCEPT_SIGNAL_AND_SIGACTION 1 #else diff --git a/libsanitizer/asan/asan_interceptors.cc b/libsanitizer/asan/asan_interceptors.cc index 8e15d341b8c..5b544c87fcb 100644 --- a/libsanitizer/asan/asan_interceptors.cc +++ b/libsanitizer/asan/asan_interceptors.cc @@ -134,6 +134,28 @@ DEFINE_REAL(int, sigaction, int signum, const struct sigaction *act, struct sigaction *oldact); #endif // ASAN_INTERCEPT_SIGNAL_AND_SIGACTION +#if ASAN_INTERCEPT_SWAPCONTEXT +INTERCEPTOR(int, swapcontext, struct ucontext_t *oucp, + struct ucontext_t *ucp) { + static bool reported_warning = false; + if (!reported_warning) { + Report("WARNING: ASan doesn't fully support makecontext/swapcontext " + "functions and may produce false positives in some cases!\n"); + reported_warning = true; + } + // Clear shadow memory for new context (it may share stack + // with current context). + ClearShadowMemoryForContext(ucp); + int res = REAL(swapcontext)(oucp, ucp); + // swapcontext technically does not return, but program may swap context to + // "oucp" later, that would look as if swapcontext() returned 0. + // We need to clear shadow for ucp once again, as it may be in arbitrary + // state. + ClearShadowMemoryForContext(ucp); + return res; +} +#endif + INTERCEPTOR(void, longjmp, void *env, int val) { __asan_handle_no_return(); REAL(longjmp)(env, val); @@ -237,13 +259,17 @@ INTERCEPTOR(void*, memcpy, void *to, const void *from, uptr size) { ASAN_WRITE_RANGE(from, size); ASAN_READ_RANGE(to, size); } +#if MAC_INTERPOSE_FUNCTIONS + // Interposing of resolver functions is broken on Mac OS 10.7 and 10.8. + // See also http://code.google.com/p/address-sanitizer/issues/detail?id=116. + return internal_memcpy(to, from, size); +#else return REAL(memcpy)(to, from, size); +#endif } INTERCEPTOR(void*, memmove, void *to, const void *from, uptr size) { -#if MAC_INTERPOSE_FUNCTIONS - if (!asan_inited) return REAL(memmove)(to, from, size); -#endif + if (!asan_inited) return internal_memmove(to, from, size); if (asan_init_is_running) { return REAL(memmove)(to, from, size); } @@ -252,7 +278,13 @@ INTERCEPTOR(void*, memmove, void *to, const void *from, uptr size) { ASAN_WRITE_RANGE(from, size); ASAN_READ_RANGE(to, size); } +#if MAC_INTERPOSE_FUNCTIONS + // Interposing of resolver functions is broken on Mac OS 10.7 and 10.8. + // See also http://code.google.com/p/address-sanitizer/issues/detail?id=116. + return internal_memmove(to, from, size); +#else return REAL(memmove)(to, from, size); +#endif } INTERCEPTOR(void*, memset, void *block, int c, uptr size) { @@ -370,6 +402,14 @@ INTERCEPTOR(char*, strcpy, char *to, const char *from) { // NOLINT #if ASAN_INTERCEPT_STRDUP INTERCEPTOR(char*, strdup, const char *s) { +#if MAC_INTERPOSE_FUNCTIONS + // FIXME: because internal_strdup() uses InternalAlloc(), which currently + // just calls malloc() on Mac, we can't use internal_strdup() with the + // dynamic runtime. We can remove the call to REAL(strdup) once InternalAlloc + // starts using mmap() instead. + // See also http://code.google.com/p/address-sanitizer/issues/detail?id=123. + if (!asan_inited) return REAL(strdup)(s); +#endif if (!asan_inited) return internal_strdup(s); ENSURE_ASAN_INITED(); if (flags()->replace_str) { @@ -669,6 +709,9 @@ void InitializeAsanInterceptors() { ASAN_INTERCEPT_FUNC(sigaction); ASAN_INTERCEPT_FUNC(signal); #endif +#if ASAN_INTERCEPT_SWAPCONTEXT + ASAN_INTERCEPT_FUNC(swapcontext); +#endif #if ASAN_INTERCEPT__LONGJMP ASAN_INTERCEPT_FUNC(_longjmp); #endif diff --git a/libsanitizer/asan/asan_internal.h b/libsanitizer/asan/asan_internal.h index 21368eef7c9..3a70ca44fd5 100644 --- a/libsanitizer/asan/asan_internal.h +++ b/libsanitizer/asan/asan_internal.h @@ -114,6 +114,7 @@ bool AsanInterceptsSignal(int signum); void SetAlternateSignalStack(); void UnsetAlternateSignalStack(); void InstallSignalHandlers(); +void ClearShadowMemoryForContext(void *context); void AsanPlatformThreadInit(); // Wrapper for TLS/TSD. diff --git a/libsanitizer/asan/asan_linux.cc b/libsanitizer/asan/asan_linux.cc index ea7ee9e7bc8..7295216b85d 100644 --- a/libsanitizer/asan/asan_linux.cc +++ b/libsanitizer/asan/asan_linux.cc @@ -66,6 +66,13 @@ void GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp) { *pc = ucontext->uc_mcontext.gregs[REG_EIP]; *bp = ucontext->uc_mcontext.gregs[REG_EBP]; *sp = ucontext->uc_mcontext.gregs[REG_ESP]; +# elif defined(__powerpc__) || defined(__powerpc64__) + ucontext_t *ucontext = (ucontext_t*)context; + *pc = ucontext->uc_mcontext.regs->nip; + *sp = ucontext->uc_mcontext.regs->gpr[PT_R1]; + // The powerpc{,64}-linux ABIs do not specify r31 as the frame + // pointer, but GCC always uses r31 when we need a frame pointer. + *bp = ucontext->uc_mcontext.regs->gpr[PT_R31]; # elif defined(__sparc__) ucontext_t *ucontext = (ucontext_t*)context; uptr *stk_ptr; @@ -149,8 +156,10 @@ void GetStackTrace(StackTrace *stack, uptr max_s, uptr pc, uptr bp) { stack->trace[0] = pc; if ((max_s) > 1) { stack->max_size = max_s; -#ifdef __arm__ +#if defined(__arm__) || defined(__powerpc__) || defined(__powerpc64__) _Unwind_Backtrace(Unwind_Trace, stack); + // Pop off the two ASAN functions from the backtrace. + stack->PopStackFrames(2); #else if (!asan_inited) return; if (AsanThread *t = asanThreadRegistry().GetCurrent()) @@ -159,6 +168,23 @@ void GetStackTrace(StackTrace *stack, uptr max_s, uptr pc, uptr bp) { } } +#if !ASAN_ANDROID +void ClearShadowMemoryForContext(void *context) { + ucontext_t *ucp = (ucontext_t*)context; + uptr sp = (uptr)ucp->uc_stack.ss_sp; + uptr size = ucp->uc_stack.ss_size; + // Align to page size. + uptr bottom = sp & ~(kPageSize - 1); + size += sp - bottom; + size = RoundUpTo(size, kPageSize); + PoisonShadow(bottom, size, 0); +} +#else +void ClearShadowMemoryForContext(void *context) { + UNIMPLEMENTED(); +} +#endif + } // namespace __asan #endif // __linux__ diff --git a/libsanitizer/asan/asan_mac.cc b/libsanitizer/asan/asan_mac.cc index 81e25e8ef59..ae5edd97165 100644 --- a/libsanitizer/asan/asan_mac.cc +++ b/libsanitizer/asan/asan_mac.cc @@ -40,7 +40,7 @@ namespace __asan { void GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp) { ucontext_t *ucontext = (ucontext_t*)context; -# if __WORDSIZE == 64 +# if SANITIZER_WORDSIZE == 64 *pc = ucontext->uc_mcontext->__ss.__rip; *bp = ucontext->uc_mcontext->__ss.__rbp; *sp = ucontext->uc_mcontext->__ss.__rsp; @@ -48,7 +48,7 @@ void GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp) { *pc = ucontext->uc_mcontext->__ss.__eip; *bp = ucontext->uc_mcontext->__ss.__ebp; *sp = ucontext->uc_mcontext->__ss.__esp; -# endif // __WORDSIZE +# endif // SANITIZER_WORDSIZE } int GetMacosVersion() { @@ -66,6 +66,7 @@ int GetMacosVersion() { switch (version[1]) { case '0': return MACOS_VERSION_SNOW_LEOPARD; case '1': return MACOS_VERSION_LION; + case '2': return MACOS_VERSION_MOUNTAIN_LION; default: return MACOS_VERSION_UNKNOWN; } } @@ -128,7 +129,14 @@ bool AsanInterceptsSignal(int signum) { } void AsanPlatformThreadInit() { - ReplaceCFAllocator(); + // For the first program thread, we can't replace the allocator before + // __CFInitialize() has been called. If it hasn't, we'll call + // MaybeReplaceCFAllocator() later on this thread. + // For other threads __CFInitialize() has been called before their creation. + // See also asan_malloc_mac.cc. + if (((CFRuntimeBase*)kCFAllocatorSystemDefault)->_cfisa) { + MaybeReplaceCFAllocator(); + } } AsanLock::AsanLock(LinkerInitialized) { @@ -161,6 +169,10 @@ void GetStackTrace(StackTrace *stack, uptr max_s, uptr pc, uptr bp) { } } +void ClearShadowMemoryForContext(void *context) { + UNIMPLEMENTED(); +} + // The range of pages to be used for escape islands. // TODO(glider): instead of mapping a fixed range we must find a range of // unmapped pages in vmmap and take them. @@ -169,7 +181,7 @@ void GetStackTrace(StackTrace *stack, uptr max_s, uptr pc, uptr bp) { // kHighMemBeg or kHighMemEnd. static void *island_allocator_pos = 0; -#if __WORDSIZE == 32 +#if SANITIZER_WORDSIZE == 32 # define kIslandEnd (0xffdf0000 - kPageSize) # define kIslandBeg (kIslandEnd - 256 * kPageSize) #else diff --git a/libsanitizer/asan/asan_mac.h b/libsanitizer/asan/asan_mac.h index 18aca0dd84e..2c162fb0c39 100644 --- a/libsanitizer/asan/asan_mac.h +++ b/libsanitizer/asan/asan_mac.h @@ -38,7 +38,8 @@ enum { MACOS_VERSION_UNKNOWN = 0, MACOS_VERSION_LEOPARD, MACOS_VERSION_SNOW_LEOPARD, - MACOS_VERSION_LION + MACOS_VERSION_LION, + MACOS_VERSION_MOUNTAIN_LION }; // Used by asan_malloc_mac.cc and asan_mac.cc @@ -47,7 +48,7 @@ extern "C" void __CFInitialize(); namespace __asan { int GetMacosVersion(); -void ReplaceCFAllocator(); +void MaybeReplaceCFAllocator(); } // namespace __asan diff --git a/libsanitizer/asan/asan_malloc_mac.cc b/libsanitizer/asan/asan_malloc_mac.cc index 2df34845f12..3f281c9cc3b 100644 --- a/libsanitizer/asan/asan_malloc_mac.cc +++ b/libsanitizer/asan/asan_malloc_mac.cc @@ -95,10 +95,6 @@ INTERCEPTOR(void, free, void *ptr) { } } -namespace __asan { - void ReplaceCFAllocator(); -} - // We can't always replace the default CFAllocator with cf_asan right in // ReplaceSystemMalloc(), because it is sometimes called before // __CFInitialize(), when the default allocator is invalid and replacing it may @@ -116,7 +112,7 @@ INTERCEPTOR(void, __CFInitialize, void) { CHECK(asan_inited); #endif REAL(__CFInitialize)(); - if (!cf_asan && asan_inited) ReplaceCFAllocator(); + if (!cf_asan && asan_inited) MaybeReplaceCFAllocator(); } namespace { @@ -291,12 +287,10 @@ size_t mi_good_size(malloc_zone_t *zone, size_t size) { boolean_t mi_check(malloc_zone_t *zone) { UNIMPLEMENTED(); - return true; } void mi_print(malloc_zone_t *zone, boolean_t verbose) { UNIMPLEMENTED(); - return; } void mi_log(malloc_zone_t *zone, void *address) { @@ -331,7 +325,7 @@ boolean_t mi_zone_locked(malloc_zone_t *zone) { extern int __CFRuntimeClassTableSize; namespace __asan { -void ReplaceCFAllocator() { +void MaybeReplaceCFAllocator() { static CFAllocatorContext asan_context = { /*version*/ 0, /*info*/ &asan_zone, /*retain*/ 0, /*release*/ 0, @@ -342,7 +336,7 @@ void ReplaceCFAllocator() { /*preferredSize*/ 0 }; if (!cf_asan) cf_asan = CFAllocatorCreate(kCFAllocatorUseContext, &asan_context); - if (CFAllocatorGetDefault() != cf_asan) + if (flags()->replace_cfallocator && CFAllocatorGetDefault() != cf_asan) CFAllocatorSetDefault(cf_asan); } @@ -410,16 +404,14 @@ void ReplaceSystemMalloc() { // Make sure the default allocator was replaced. CHECK(malloc_default_zone() == &asan_zone); - if (flags()->replace_cfallocator) { - // If __CFInitialize() hasn't been called yet, cf_asan will be created and - // installed as the default allocator after __CFInitialize() finishes (see - // the interceptor for __CFInitialize() above). Otherwise install cf_asan - // right now. On both Snow Leopard and Lion __CFInitialize() calls - // __CFAllocatorInitialize(), which initializes the _base._cfisa field of - // the default allocators we check here. - if (((CFRuntimeBase*)kCFAllocatorSystemDefault)->_cfisa) { - ReplaceCFAllocator(); - } + // If __CFInitialize() hasn't been called yet, cf_asan will be created and + // installed as the default allocator after __CFInitialize() finishes (see + // the interceptor for __CFInitialize() above). Otherwise install cf_asan + // right now. On both Snow Leopard and Lion __CFInitialize() calls + // __CFAllocatorInitialize(), which initializes the _base._cfisa field of + // the default allocators we check here. + if (((CFRuntimeBase*)kCFAllocatorSystemDefault)->_cfisa) { + MaybeReplaceCFAllocator(); } } } // namespace __asan diff --git a/libsanitizer/asan/asan_mapping.h b/libsanitizer/asan/asan_mapping.h index 40a38db0544..c93280fdd6c 100644 --- a/libsanitizer/asan/asan_mapping.h +++ b/libsanitizer/asan/asan_mapping.h @@ -28,10 +28,14 @@ extern __attribute__((visibility("default"))) uptr __asan_mapping_offset; # define SHADOW_OFFSET (0) # else # define SHADOW_SCALE (3) -# if __WORDSIZE == 32 +# if SANITIZER_WORDSIZE == 32 # define SHADOW_OFFSET (1 << 29) # else -# define SHADOW_OFFSET (1ULL << 44) +# if defined(__powerpc64__) +# define SHADOW_OFFSET (1ULL << 41) +# else +# define SHADOW_OFFSET (1ULL << 44) +# endif # endif # endif #endif // ASAN_FLEXIBLE_MAPPING_AND_OFFSET @@ -40,11 +44,15 @@ extern __attribute__((visibility("default"))) uptr __asan_mapping_offset; #define MEM_TO_SHADOW(mem) (((mem) >> SHADOW_SCALE) | (SHADOW_OFFSET)) #define SHADOW_TO_MEM(shadow) (((shadow) - SHADOW_OFFSET) << SHADOW_SCALE) -#if __WORDSIZE == 64 +#if SANITIZER_WORDSIZE == 64 +# if defined(__powerpc64__) + static const uptr kHighMemEnd = 0x00000fffffffffffUL; +# else static const uptr kHighMemEnd = 0x00007fffffffffffUL; -#else // __WORDSIZE == 32 +# endif +#else // SANITIZER_WORDSIZE == 32 static const uptr kHighMemEnd = 0xffffffff; -#endif // __WORDSIZE +#endif // SANITIZER_WORDSIZE #define kLowMemBeg 0 diff --git a/libsanitizer/asan/asan_new_delete.cc b/libsanitizer/asan/asan_new_delete.cc index a2180ae9444..8132e58b6e2 100644 --- a/libsanitizer/asan/asan_new_delete.cc +++ b/libsanitizer/asan/asan_new_delete.cc @@ -15,7 +15,6 @@ #include "asan_stack.h" #include <stddef.h> -#include <new> namespace __asan { // This function is a no-op. We need it to make sure that object file @@ -26,29 +25,40 @@ void ReplaceOperatorsNewAndDelete() { } using namespace __asan; // NOLINT +// On Android new() goes through malloc interceptors. +#if !ASAN_ANDROID + +// Fake std::nothrow_t to avoid including <new>. +namespace std { +struct nothrow_t {}; +} // namespace std + #define OPERATOR_NEW_BODY \ GET_STACK_TRACE_HERE_FOR_MALLOC;\ return asan_memalign(0, size, &stack); -#if ASAN_ANDROID +INTERCEPTOR_ATTRIBUTE void *operator new(size_t size) { OPERATOR_NEW_BODY; } +INTERCEPTOR_ATTRIBUTE void *operator new[](size_t size) { OPERATOR_NEW_BODY; } -#else -void *operator new(size_t size) throw(std::bad_alloc) { OPERATOR_NEW_BODY; } -void *operator new[](size_t size) throw(std::bad_alloc) { OPERATOR_NEW_BODY; } -void *operator new(size_t size, std::nothrow_t const&) throw() -{ OPERATOR_NEW_BODY; } -void *operator new[](size_t size, std::nothrow_t const&) throw() -{ OPERATOR_NEW_BODY; } -#endif +INTERCEPTOR_ATTRIBUTE +void *operator new(size_t size, std::nothrow_t const&) { OPERATOR_NEW_BODY; } +INTERCEPTOR_ATTRIBUTE +void *operator new[](size_t size, std::nothrow_t const&) { OPERATOR_NEW_BODY; } #define OPERATOR_DELETE_BODY \ GET_STACK_TRACE_HERE_FOR_FREE(ptr);\ asan_free(ptr, &stack); -void operator delete(void *ptr) throw() { OPERATOR_DELETE_BODY; } -void operator delete[](void *ptr) throw() { OPERATOR_DELETE_BODY; } -void operator delete(void *ptr, std::nothrow_t const&) throw() +INTERCEPTOR_ATTRIBUTE +void operator delete(void *ptr) { OPERATOR_DELETE_BODY; } +INTERCEPTOR_ATTRIBUTE +void operator delete[](void *ptr) { OPERATOR_DELETE_BODY; } +INTERCEPTOR_ATTRIBUTE +void operator delete(void *ptr, std::nothrow_t const&) { OPERATOR_DELETE_BODY; } -void operator delete[](void *ptr, std::nothrow_t const&) throw() +INTERCEPTOR_ATTRIBUTE +void operator delete[](void *ptr, std::nothrow_t const&) { OPERATOR_DELETE_BODY; } + +#endif diff --git a/libsanitizer/asan/asan_report.cc b/libsanitizer/asan/asan_report.cc index 7e6381c2beb..c35b4ec14f7 100644 --- a/libsanitizer/asan/asan_report.cc +++ b/libsanitizer/asan/asan_report.cc @@ -42,7 +42,7 @@ void AppendToErrorMessageBuffer(const char *buffer) { static void PrintBytes(const char *before, uptr *a) { u8 *bytes = (u8*)a; - uptr byte_num = (__WORDSIZE) / 8; + uptr byte_num = (SANITIZER_WORDSIZE) / 8; Printf("%s%p:", before, (void*)a); for (uptr i = 0; i < byte_num; i++) { Printf(" %x%x", bytes[i] >> 4, bytes[i] & 15); @@ -178,7 +178,7 @@ bool DescribeAddressIfStack(uptr addr, uptr access_size) { Printf(" [%zu, %zu) '%s'\n", beg, beg + size, buf); } Printf("HINT: this may be a false positive if your program uses " - "some custom stack unwind mechanism\n" + "some custom stack unwind mechanism or swapcontext\n" " (longjmp and C++ exceptions *are* supported)\n"); DescribeThread(t->summary()); return true; @@ -287,7 +287,9 @@ class ScopedInErrorReport { // an error report will finish doing it. SleepForSeconds(Max(100, flags()->sleep_before_dying + 1)); } - Die(); + // If we're still not dead for some reason, use raw Exit() instead of + // Die() to bypass any additional checks. + Exit(flags()->exitcode); } __asan_on_error(); reporting_thread_tid = asanThreadRegistry().GetCurrentTidOrInvalid(); @@ -320,7 +322,7 @@ class ScopedInErrorReport { void ReportSIGSEGV(uptr pc, uptr sp, uptr bp, uptr addr) { ScopedInErrorReport in_report; - Report("ERROR: AddressSanitizer crashed on unknown address %p" + Report("ERROR: AddressSanitizer: SEGV on unknown address %p" " (pc %p sp %p bp %p T%d)\n", (void*)addr, (void*)pc, (void*)sp, (void*)bp, asanThreadRegistry().GetCurrentTidOrInvalid()); @@ -331,14 +333,14 @@ void ReportSIGSEGV(uptr pc, uptr sp, uptr bp, uptr addr) { void ReportDoubleFree(uptr addr, StackTrace *stack) { ScopedInErrorReport in_report; - Report("ERROR: AddressSanitizer attempting double-free on %p:\n", addr); + Report("ERROR: AddressSanitizer: attempting double-free on %p:\n", addr); PrintStack(stack); DescribeHeapAddress(addr, 1); } void ReportFreeNotMalloced(uptr addr, StackTrace *stack) { ScopedInErrorReport in_report; - Report("ERROR: AddressSanitizer attempting free on address " + Report("ERROR: AddressSanitizer: attempting free on address " "which was not malloc()-ed: %p\n", addr); PrintStack(stack); DescribeHeapAddress(addr, 1); @@ -346,7 +348,7 @@ void ReportFreeNotMalloced(uptr addr, StackTrace *stack) { void ReportMallocUsableSizeNotOwned(uptr addr, StackTrace *stack) { ScopedInErrorReport in_report; - Report("ERROR: AddressSanitizer attempting to call " + Report("ERROR: AddressSanitizer: attempting to call " "malloc_usable_size() for pointer which is " "not owned: %p\n", addr); PrintStack(stack); @@ -355,7 +357,7 @@ void ReportMallocUsableSizeNotOwned(uptr addr, StackTrace *stack) { void ReportAsanGetAllocatedSizeNotOwned(uptr addr, StackTrace *stack) { ScopedInErrorReport in_report; - Report("ERROR: AddressSanitizer attempting to call " + Report("ERROR: AddressSanitizer: attempting to call " "__asan_get_allocated_size() for pointer which is " "not owned: %p\n", addr); PrintStack(stack); @@ -366,7 +368,7 @@ void ReportStringFunctionMemoryRangesOverlap( const char *function, const char *offset1, uptr length1, const char *offset2, uptr length2, StackTrace *stack) { ScopedInErrorReport in_report; - Report("ERROR: AddressSanitizer %s-param-overlap: " + Report("ERROR: AddressSanitizer: %s-param-overlap: " "memory ranges [%p,%p) and [%p, %p) overlap\n", \ function, offset1, offset1 + length1, offset2, offset2 + length2); PrintStack(stack); @@ -459,7 +461,7 @@ void __asan_report_error(uptr pc, uptr bp, uptr sp, } } - Report("ERROR: AddressSanitizer %s on address " + Report("ERROR: AddressSanitizer: %s on address " "%p at pc 0x%zx bp 0x%zx sp 0x%zx\n", bug_descr, (void*)addr, pc, bp, sp); diff --git a/libsanitizer/asan/asan_rtl.cc b/libsanitizer/asan/asan_rtl.cc index 442d41c4f23..7731c17a351 100644 --- a/libsanitizer/asan/asan_rtl.cc +++ b/libsanitizer/asan/asan_rtl.cc @@ -132,7 +132,7 @@ void InitializeFlags(Flags *f, const char *env) { f->unmap_shadow_on_exit = false; f->abort_on_error = false; f->atexit = false; - f->disable_core = (__WORDSIZE == 64); + f->disable_core = (SANITIZER_WORDSIZE == 64); f->strip_path_prefix = ""; f->allow_reexec = true; f->print_full_thread_history = true; diff --git a/libsanitizer/asan/asan_stats.cc b/libsanitizer/asan/asan_stats.cc index fa4adcb7f9a..ecdf5ffad09 100644 --- a/libsanitizer/asan/asan_stats.cc +++ b/libsanitizer/asan/asan_stats.cc @@ -54,7 +54,8 @@ void AsanStats::Print() { static AsanLock print_lock(LINKER_INITIALIZED); static void PrintAccumulatedStats() { - AsanStats stats = asanThreadRegistry().GetAccumulatedStats(); + AsanStats stats; + asanThreadRegistry().GetAccumulatedStats(&stats); // Use lock to keep reports from mixing up. ScopedLock lock(&print_lock); stats.Print(); diff --git a/libsanitizer/asan/asan_thread.cc b/libsanitizer/asan/asan_thread.cc index 9295c1570ec..4ec98e5ed22 100644 --- a/libsanitizer/asan/asan_thread.cc +++ b/libsanitizer/asan/asan_thread.cc @@ -116,25 +116,25 @@ void AsanThread::ClearShadowForThreadStack() { const char *AsanThread::GetFrameNameByAddr(uptr addr, uptr *offset) { uptr bottom = 0; - bool is_fake_stack = false; if (AddrIsInStack(addr)) { bottom = stack_bottom(); } else { bottom = fake_stack().AddrIsInFakeStack(addr); CHECK(bottom); - is_fake_stack = true; + *offset = addr - bottom; + return (const char *)((uptr*)bottom)[1]; } - uptr aligned_addr = addr & ~(__WORDSIZE/8 - 1); // align addr. + uptr aligned_addr = addr & ~(SANITIZER_WORDSIZE/8 - 1); // align addr. u8 *shadow_ptr = (u8*)MemToShadow(aligned_addr); u8 *shadow_bottom = (u8*)MemToShadow(bottom); while (shadow_ptr >= shadow_bottom && - *shadow_ptr != kAsanStackLeftRedzoneMagic) { + *shadow_ptr != kAsanStackLeftRedzoneMagic) { shadow_ptr--; } while (shadow_ptr >= shadow_bottom && - *shadow_ptr == kAsanStackLeftRedzoneMagic) { + *shadow_ptr == kAsanStackLeftRedzoneMagic) { shadow_ptr--; } @@ -144,8 +144,7 @@ const char *AsanThread::GetFrameNameByAddr(uptr addr, uptr *offset) { } uptr* ptr = (uptr*)SHADOW_TO_MEM((uptr)(shadow_ptr + 1)); - CHECK((ptr[0] == kCurrentStackFrameMagic) || - (is_fake_stack && ptr[0] == kRetiredStackFrameMagic)); + CHECK(ptr[0] == kCurrentStackFrameMagic); *offset = addr - (uptr)ptr; return (const char*)ptr[1]; } diff --git a/libsanitizer/asan/asan_thread_registry.cc b/libsanitizer/asan/asan_thread_registry.cc index 840837e0004..9858cce22b0 100644 --- a/libsanitizer/asan/asan_thread_registry.cc +++ b/libsanitizer/asan/asan_thread_registry.cc @@ -102,16 +102,20 @@ AsanStats &AsanThreadRegistry::GetCurrentThreadStats() { return (t) ? t->stats() : main_thread_.stats(); } -AsanStats AsanThreadRegistry::GetAccumulatedStats() { +void AsanThreadRegistry::GetAccumulatedStats(AsanStats *stats) { ScopedLock lock(&mu_); UpdateAccumulatedStatsUnlocked(); - return accumulated_stats_; + internal_memcpy(stats, &accumulated_stats_, sizeof(accumulated_stats_)); } uptr AsanThreadRegistry::GetCurrentAllocatedBytes() { ScopedLock lock(&mu_); UpdateAccumulatedStatsUnlocked(); - return accumulated_stats_.malloced - accumulated_stats_.freed; + uptr malloced = accumulated_stats_.malloced; + uptr freed = accumulated_stats_.freed; + // Return sane value if malloced < freed due to racy + // way we update accumulated stats. + return (malloced > freed) ? malloced - freed : 1; } uptr AsanThreadRegistry::GetHeapSize() { @@ -123,11 +127,14 @@ uptr AsanThreadRegistry::GetHeapSize() { uptr AsanThreadRegistry::GetFreeBytes() { ScopedLock lock(&mu_); UpdateAccumulatedStatsUnlocked(); - return accumulated_stats_.mmaped - - accumulated_stats_.malloced - - accumulated_stats_.malloced_redzones - + accumulated_stats_.really_freed - + accumulated_stats_.really_freed_redzones; + uptr total_free = accumulated_stats_.mmaped + + accumulated_stats_.really_freed + + accumulated_stats_.really_freed_redzones; + uptr total_used = accumulated_stats_.malloced + + accumulated_stats_.malloced_redzones; + // Return sane value if total_free < total_used due to racy + // way we update accumulated stats. + return (total_free > total_used) ? total_free - total_used : 1; } // Return several stats counters with a single call to diff --git a/libsanitizer/asan/asan_thread_registry.h b/libsanitizer/asan/asan_thread_registry.h index 99d5cb56af0..bb6b2678faa 100644 --- a/libsanitizer/asan/asan_thread_registry.h +++ b/libsanitizer/asan/asan_thread_registry.h @@ -45,9 +45,9 @@ class AsanThreadRegistry { // Returns stats for GetCurrent(), or stats for // T0 if GetCurrent() returns 0. AsanStats &GetCurrentThreadStats(); - // Flushes all thread-local stats to accumulated stats, and returns + // Flushes all thread-local stats to accumulated stats, and makes // a copy of accumulated stats. - AsanStats GetAccumulatedStats(); + void GetAccumulatedStats(AsanStats *stats); uptr GetCurrentAllocatedBytes(); uptr GetHeapSize(); uptr GetFreeBytes(); diff --git a/libsanitizer/asan/asan_win.cc b/libsanitizer/asan/asan_win.cc index a5c0441dafa..8b7f9ef0e38 100644 --- a/libsanitizer/asan/asan_win.cc +++ b/libsanitizer/asan/asan_win.cc @@ -137,6 +137,10 @@ void AsanPlatformThreadInit() { // Nothing here for now. } +void ClearShadowMemoryForContext(void *context) { + UNIMPLEMENTED(); +} + } // namespace __asan // ---------------------- Interface ---------------- {{{1 |