diff options
author | Martin Liska <mliska@suse.cz> | 2019-11-05 14:54:57 +0100 |
---|---|---|
committer | Martin Liska <marxin@gcc.gnu.org> | 2019-11-05 13:54:57 +0000 |
commit | 3ca75cd55030a53a858bdbe9aba6d87f6b1e90b8 (patch) | |
tree | c3eb5c5658e168b819d23dd20aa46d614089c649 /libsanitizer/tsan | |
parent | 9bae89924afc811bd10e249856bf78dd19f20df2 (diff) | |
download | gcc-3ca75cd55030a53a858bdbe9aba6d87f6b1e90b8.zip gcc-3ca75cd55030a53a858bdbe9aba6d87f6b1e90b8.tar.gz gcc-3ca75cd55030a53a858bdbe9aba6d87f6b1e90b8.tar.bz2 |
Libsanitizer: merge from trunk with merge.sh.
2019-11-05 Martin Liska <mliska@suse.cz>
* all source files: Merge from upstream r375507.
From-SVN: r277834
Diffstat (limited to 'libsanitizer/tsan')
24 files changed, 182 insertions, 59 deletions
diff --git a/libsanitizer/tsan/tsan_dispatch_defs.h b/libsanitizer/tsan/tsan_dispatch_defs.h index 6f1d1f7..298297a 100644 --- a/libsanitizer/tsan/tsan_dispatch_defs.h +++ b/libsanitizer/tsan/tsan_dispatch_defs.h @@ -31,11 +31,11 @@ typedef void (^dispatch_block_t)(void); typedef void (^dispatch_io_handler_t)(bool done, dispatch_data_t data, int error); -typedef long dispatch_once_t; // NOLINT +typedef long dispatch_once_t; typedef __sanitizer::u64 dispatch_time_t; -typedef int dispatch_fd_t; // NOLINT -typedef unsigned long dispatch_io_type_t; // NOLINT -typedef unsigned long dispatch_io_close_flags_t; // NOLINT +typedef int dispatch_fd_t; +typedef unsigned long dispatch_io_type_t; +typedef unsigned long dispatch_io_close_flags_t; extern "C" { void *dispatch_get_context(dispatch_object_t object); @@ -57,10 +57,10 @@ extern const dispatch_block_t _dispatch_data_destructor_munmap; #endif // Data types used in dispatch APIs -typedef unsigned long size_t; // NOLINT -typedef unsigned long uintptr_t; // NOLINT +typedef unsigned long size_t; +typedef unsigned long uintptr_t; typedef __sanitizer::s64 off_t; typedef __sanitizer::u16 mode_t; -typedef long long_t; // NOLINT +typedef long long_t; #endif // TSAN_DISPATCH_DEFS_H diff --git a/libsanitizer/tsan/tsan_external.cpp b/libsanitizer/tsan/tsan_external.cpp index efc1013..0faa1ee 100644 --- a/libsanitizer/tsan/tsan_external.cpp +++ b/libsanitizer/tsan/tsan_external.cpp @@ -25,7 +25,7 @@ static TagData registered_tags[kExternalTagMax] = { {}, {"Swift variable", "Swift access race"}, }; -static atomic_uint32_t used_tags{kExternalTagFirstUserAvailable}; // NOLINT. +static atomic_uint32_t used_tags{kExternalTagFirstUserAvailable}; static TagData *GetTagData(uptr tag) { // Invalid/corrupted tag? Better return NULL and let the caller deal with it. if (tag >= atomic_load(&used_tags, memory_order_relaxed)) return nullptr; diff --git a/libsanitizer/tsan/tsan_fd.cpp b/libsanitizer/tsan/tsan_fd.cpp index db01d80..50a6b56 100644 --- a/libsanitizer/tsan/tsan_fd.cpp +++ b/libsanitizer/tsan/tsan_fd.cpp @@ -86,7 +86,8 @@ static FdDesc *fddesc(ThreadState *thr, uptr pc, int fd) { else user_free(thr, pc, p, false); } - return &((FdDesc*)l1)[fd % kTableSizeL2]; // NOLINT + FdDesc *fds = reinterpret_cast<FdDesc *>(l1); + return &fds[fd % kTableSizeL2]; } // pd must be already ref'ed. diff --git a/libsanitizer/tsan/tsan_libdispatch.cpp b/libsanitizer/tsan/tsan_interceptors_libdispatch.cpp index 5e86ddc..5dacd32 100644 --- a/libsanitizer/tsan/tsan_libdispatch.cpp +++ b/libsanitizer/tsan/tsan_interceptors_libdispatch.cpp @@ -1,4 +1,4 @@ -//===-- tsan_libdispatch.cpp ----------------------------------------------===// +//===-- tsan_interceptors_libdispatch.cpp ---------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -16,6 +16,7 @@ #include "tsan_interceptors.h" #include "tsan_rtl.h" +#include "BlocksRuntime/Block.h" #include "tsan_dispatch_defs.h" namespace __tsan { diff --git a/libsanitizer/tsan/tsan_interceptors_mac.cpp b/libsanitizer/tsan/tsan_interceptors_mac.cpp index c2083f8..aa29536 100644 --- a/libsanitizer/tsan/tsan_interceptors_mac.cpp +++ b/libsanitizer/tsan/tsan_interceptors_mac.cpp @@ -23,13 +23,14 @@ #include <errno.h> #include <libkern/OSAtomic.h> #include <objc/objc-sync.h> +#include <os/lock.h> #include <sys/ucontext.h> #if defined(__has_include) && __has_include(<xpc/xpc.h>) #include <xpc/xpc.h> #endif // #if defined(__has_include) && __has_include(<xpc/xpc.h>) -typedef long long_t; // NOLINT +typedef long long_t; extern "C" { int getcontext(ucontext_t *ucp) __attribute__((returns_twice)); @@ -246,6 +247,45 @@ TSAN_INTERCEPTOR(void, os_lock_unlock, void *lock) { REAL(os_lock_unlock)(lock); } +TSAN_INTERCEPTOR(void, os_unfair_lock_lock, os_unfair_lock_t lock) { + if (!cur_thread()->is_inited || cur_thread()->is_dead) { + return REAL(os_unfair_lock_lock)(lock); + } + SCOPED_TSAN_INTERCEPTOR(os_unfair_lock_lock, lock); + REAL(os_unfair_lock_lock)(lock); + Acquire(thr, pc, (uptr)lock); +} + +TSAN_INTERCEPTOR(void, os_unfair_lock_lock_with_options, os_unfair_lock_t lock, + u32 options) { + if (!cur_thread()->is_inited || cur_thread()->is_dead) { + return REAL(os_unfair_lock_lock_with_options)(lock, options); + } + SCOPED_TSAN_INTERCEPTOR(os_unfair_lock_lock_with_options, lock, options); + REAL(os_unfair_lock_lock_with_options)(lock, options); + Acquire(thr, pc, (uptr)lock); +} + +TSAN_INTERCEPTOR(bool, os_unfair_lock_trylock, os_unfair_lock_t lock) { + if (!cur_thread()->is_inited || cur_thread()->is_dead) { + return REAL(os_unfair_lock_trylock)(lock); + } + SCOPED_TSAN_INTERCEPTOR(os_unfair_lock_trylock, lock); + bool result = REAL(os_unfair_lock_trylock)(lock); + if (result) + Acquire(thr, pc, (uptr)lock); + return result; +} + +TSAN_INTERCEPTOR(void, os_unfair_lock_unlock, os_unfair_lock_t lock) { + if (!cur_thread()->is_inited || cur_thread()->is_dead) { + return REAL(os_unfair_lock_unlock)(lock); + } + SCOPED_TSAN_INTERCEPTOR(os_unfair_lock_unlock, lock); + Release(thr, pc, (uptr)lock); + REAL(os_unfair_lock_unlock)(lock); +} + #if defined(__has_include) && __has_include(<xpc/xpc.h>) TSAN_INTERCEPTOR(void, xpc_connection_set_event_handler, diff --git a/libsanitizer/tsan/tsan_interceptors_mach_vm.cpp b/libsanitizer/tsan/tsan_interceptors_mach_vm.cpp new file mode 100644 index 0000000..cd318f8 --- /dev/null +++ b/libsanitizer/tsan/tsan_interceptors_mach_vm.cpp @@ -0,0 +1,52 @@ +//===-- tsan_interceptors_mach_vm.cpp -------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file is a part of ThreadSanitizer (TSan), a race detector. +// +// Interceptors for mach_vm_* user space memory routines on Darwin. +//===----------------------------------------------------------------------===// + +#include "interception/interception.h" +#include "tsan_interceptors.h" +#include "tsan_platform.h" + +#include <mach/mach.h> + +namespace __tsan { + +static bool intersects_with_shadow(mach_vm_address_t *address, + mach_vm_size_t size, int flags) { + // VM_FLAGS_FIXED is 0x0, so we have to test for VM_FLAGS_ANYWHERE. + if (flags & VM_FLAGS_ANYWHERE) return false; + uptr ptr = *address; + return !IsAppMem(ptr) || !IsAppMem(ptr + size - 1); +} + +TSAN_INTERCEPTOR(kern_return_t, mach_vm_allocate, vm_map_t target, + mach_vm_address_t *address, mach_vm_size_t size, int flags) { + SCOPED_TSAN_INTERCEPTOR(mach_vm_allocate, target, address, size, flags); + if (target != mach_task_self()) + return REAL(mach_vm_allocate)(target, address, size, flags); + if (intersects_with_shadow(address, size, flags)) + return KERN_NO_SPACE; + kern_return_t res = REAL(mach_vm_allocate)(target, address, size, flags); + if (res == KERN_SUCCESS) + MemoryRangeImitateWriteOrResetRange(thr, pc, *address, size); + return res; +} + +TSAN_INTERCEPTOR(kern_return_t, mach_vm_deallocate, vm_map_t target, + mach_vm_address_t address, mach_vm_size_t size) { + SCOPED_TSAN_INTERCEPTOR(mach_vm_deallocate, target, address, size); + if (target != mach_task_self()) + return REAL(mach_vm_deallocate)(target, address, size); + UnmapShadow(thr, address, size); + return REAL(mach_vm_deallocate)(target, address, size); +} + +} // namespace __tsan diff --git a/libsanitizer/tsan/tsan_interceptors.cpp b/libsanitizer/tsan/tsan_interceptors_posix.cpp index 9e1b9ed..8aea1e4 100644 --- a/libsanitizer/tsan/tsan_interceptors.cpp +++ b/libsanitizer/tsan/tsan_interceptors_posix.cpp @@ -1,4 +1,4 @@ -//===-- tsan_interceptors.cpp ---------------------------------------------===// +//===-- tsan_interceptors_posix.cpp ---------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -31,8 +31,7 @@ #include "tsan_mman.h" #include "tsan_fd.h" - -using namespace __tsan; // NOLINT +using namespace __tsan; #if SANITIZER_FREEBSD || SANITIZER_MAC #define stdout __stdoutp @@ -41,9 +40,10 @@ using namespace __tsan; // NOLINT #if SANITIZER_NETBSD #define dirfd(dirp) (*(int *)(dirp)) -#define fileno_unlocked(fp) \ - (((__sanitizer_FILE*)fp)->_file == -1 ? -1 : \ - (int)(unsigned short)(((__sanitizer_FILE*)fp)->_file)) // NOLINT +#define fileno_unlocked(fp) \ + (((__sanitizer_FILE *)fp)->_file == -1 \ + ? -1 \ + : (int)(unsigned short)(((__sanitizer_FILE *)fp)->_file)) #define stdout ((__sanitizer_FILE*)&__sF[1]) #define stderr ((__sanitizer_FILE*)&__sF[2]) @@ -114,6 +114,7 @@ const int PTHREAD_MUTEX_RECURSIVE_NP = 2; const int EPOLL_CTL_ADD = 1; #endif const int SIGILL = 4; +const int SIGTRAP = 5; const int SIGABRT = 6; const int SIGFPE = 8; const int SIGSEGV = 11; @@ -133,7 +134,7 @@ const int PTHREAD_BARRIER_SERIAL_THREAD = 1234567; const int PTHREAD_BARRIER_SERIAL_THREAD = -1; #endif const int MAP_FIXED = 0x10; -typedef long long_t; // NOLINT +typedef long long_t; // From /usr/include/unistd.h # define F_ULOCK 0 /* Unlock a previously locked region. */ @@ -723,12 +724,12 @@ TSAN_INTERCEPTOR(uptr, malloc_usable_size, void *p) { } #endif -TSAN_INTERCEPTOR(char*, strcpy, char *dst, const char *src) { // NOLINT - SCOPED_TSAN_INTERCEPTOR(strcpy, dst, src); // NOLINT +TSAN_INTERCEPTOR(char *, strcpy, char *dst, const char *src) { + SCOPED_TSAN_INTERCEPTOR(strcpy, dst, src); uptr srclen = internal_strlen(src); MemoryAccessRange(thr, pc, (uptr)dst, srclen + 1, true); MemoryAccessRange(thr, pc, (uptr)src, srclen + 1, false); - return REAL(strcpy)(dst, src); // NOLINT + return REAL(strcpy)(dst, src); } TSAN_INTERCEPTOR(char*, strncpy, char *dst, char *src, uptr n) { @@ -745,6 +746,8 @@ TSAN_INTERCEPTOR(char*, strdup, const char *str) { return REAL(strdup)(str); } +// Zero out addr if it points into shadow memory and was provided as a hint +// only, i.e., MAP_FIXED is not set. static bool fix_mmap_addr(void **addr, long_t sz, int flags) { if (*addr) { if (!IsAppMem((uptr)*addr) || !IsAppMem((uptr)*addr + sz - 1)) { @@ -767,22 +770,14 @@ static void *mmap_interceptor(ThreadState *thr, uptr pc, Mmap real_mmap, void *res = real_mmap(addr, sz, prot, flags, fd, off); if (res != MAP_FAILED) { if (fd > 0) FdAccess(thr, pc, fd); - if (thr->ignore_reads_and_writes == 0) - MemoryRangeImitateWrite(thr, pc, (uptr)res, sz); - else - MemoryResetRange(thr, pc, (uptr)res, sz); + MemoryRangeImitateWriteOrResetRange(thr, pc, (uptr)res, sz); } return res; } TSAN_INTERCEPTOR(int, munmap, void *addr, long_t sz) { SCOPED_TSAN_INTERCEPTOR(munmap, addr, sz); - if (sz != 0) { - // If sz == 0, munmap will return EINVAL and don't unmap any memory. - DontNeedShadowFor((uptr)addr, sz); - ScopedGlobalProcessor sgp; - ctx->metamap.ResetRange(thr->proc(), (uptr)addr, (uptr)sz); - } + UnmapShadow(thr, (uptr)addr, sz); int res = REAL(munmap)(addr, sz); return res; } @@ -1968,10 +1963,10 @@ void ProcessPendingSignals(ThreadState *thr) { } // namespace __tsan static bool is_sync_signal(ThreadSignalContext *sctx, int sig) { - return sig == SIGSEGV || sig == SIGBUS || sig == SIGILL || - sig == SIGABRT || sig == SIGFPE || sig == SIGPIPE || sig == SIGSYS || - // If we are sending signal to ourselves, we must process it now. - (sctx && sig == sctx->int_signal_send); + return sig == SIGSEGV || sig == SIGBUS || sig == SIGILL || sig == SIGTRAP || + sig == SIGABRT || sig == SIGFPE || sig == SIGPIPE || sig == SIGSYS || + // If we are sending signal to ourselves, we must process it now. + (sctx && sig == sctx->int_signal_send); } void ALWAYS_INLINE rtl_generic_sighandler(bool sigact, int sig, @@ -2666,7 +2661,7 @@ void InitializeInterceptors() { TSAN_MAYBE_INTERCEPT_PVALLOC; TSAN_INTERCEPT(posix_memalign); - TSAN_INTERCEPT(strcpy); // NOLINT + TSAN_INTERCEPT(strcpy); TSAN_INTERCEPT(strncpy); TSAN_INTERCEPT(strdup); diff --git a/libsanitizer/tsan/tsan_interface.cpp b/libsanitizer/tsan/tsan_interface.cpp index 845d8c8..2b3a088 100644 --- a/libsanitizer/tsan/tsan_interface.cpp +++ b/libsanitizer/tsan/tsan_interface.cpp @@ -17,7 +17,7 @@ #define CALLERPC ((uptr)__builtin_return_address(0)) -using namespace __tsan; // NOLINT +using namespace __tsan; typedef u16 uint16_t; typedef u32 uint32_t; diff --git a/libsanitizer/tsan/tsan_interface.h b/libsanitizer/tsan/tsan_interface.h index fac5780..6d7286c 100644 --- a/libsanitizer/tsan/tsan_interface.h +++ b/libsanitizer/tsan/tsan_interface.h @@ -90,9 +90,14 @@ SANITIZER_INTERFACE_ATTRIBUTE void __tsan_external_write(void *addr, void *caller_pc, void *tag); SANITIZER_INTERFACE_ATTRIBUTE -void __tsan_read_range(void *addr, unsigned long size); // NOLINT +void __tsan_read_range(void *addr, unsigned long size); SANITIZER_INTERFACE_ATTRIBUTE -void __tsan_write_range(void *addr, unsigned long size); // NOLINT +void __tsan_write_range(void *addr, unsigned long size); + +SANITIZER_INTERFACE_ATTRIBUTE +void __tsan_read_range_pc(void *addr, unsigned long size, void *pc); // NOLINT +SANITIZER_INTERFACE_ATTRIBUTE +void __tsan_write_range_pc(void *addr, unsigned long size, void *pc); // NOLINT // User may provide function that would be called right when TSan detects // an error. The argument 'report' is an opaque pointer that can be used to @@ -187,9 +192,9 @@ namespace __tsan { // These should match declarations from public tsan_interface_atomic.h header. typedef unsigned char a8; -typedef unsigned short a16; // NOLINT +typedef unsigned short a16; typedef unsigned int a32; -typedef unsigned long long a64; // NOLINT +typedef unsigned long long a64; #if !SANITIZER_GO && (defined(__SIZEOF_INT128__) \ || (__clang_major__ * 100 + __clang_minor__ >= 302)) && !defined(__mips64) __extension__ typedef __int128 a128; diff --git a/libsanitizer/tsan/tsan_interface_ann.cpp b/libsanitizer/tsan/tsan_interface_ann.cpp index 288485c..99516d9 100644 --- a/libsanitizer/tsan/tsan_interface_ann.cpp +++ b/libsanitizer/tsan/tsan_interface_ann.cpp @@ -24,7 +24,7 @@ #define CALLERPC ((uptr)__builtin_return_address(0)) -using namespace __tsan; // NOLINT +using namespace __tsan; namespace __tsan { @@ -220,7 +220,7 @@ static void ReportMissedExpectedRace(ExpectRace *race) { } } // namespace __tsan -using namespace __tsan; // NOLINT +using namespace __tsan; extern "C" { void INTERFACE_ATTRIBUTE AnnotateHappensBefore(char *f, int l, uptr addr) { diff --git a/libsanitizer/tsan/tsan_interface_atomic.cpp b/libsanitizer/tsan/tsan_interface_atomic.cpp index 730a8e6..3f459af 100644 --- a/libsanitizer/tsan/tsan_interface_atomic.cpp +++ b/libsanitizer/tsan/tsan_interface_atomic.cpp @@ -25,7 +25,7 @@ #include "tsan_interface.h" #include "tsan_rtl.h" -using namespace __tsan; // NOLINT +using namespace __tsan; #if !SANITIZER_GO && __TSAN_HAS_INT128 // Protects emulation of 128-bit atomic operations. diff --git a/libsanitizer/tsan/tsan_interface_inl.h b/libsanitizer/tsan/tsan_interface_inl.h index bf4a165..f955ddf 100644 --- a/libsanitizer/tsan/tsan_interface_inl.h +++ b/libsanitizer/tsan/tsan_interface_inl.h @@ -15,7 +15,7 @@ #define CALLERPC ((uptr)__builtin_return_address(0)) -using namespace __tsan; // NOLINT +using namespace __tsan; void __tsan_read1(void *addr) { MemoryRead(cur_thread(), CALLERPC, (uptr)addr, kSizeLog1); @@ -122,3 +122,11 @@ void __tsan_read_range(void *addr, uptr size) { void __tsan_write_range(void *addr, uptr size) { MemoryAccessRange(cur_thread(), CALLERPC, (uptr)addr, size, true); } + +void __tsan_read_range_pc(void *addr, uptr size, void *pc) { + MemoryAccessRange(cur_thread(), (uptr)pc, (uptr)addr, size, false); +} + +void __tsan_write_range_pc(void *addr, uptr size, void *pc) { + MemoryAccessRange(cur_thread(), (uptr)pc, (uptr)addr, size, true); +} diff --git a/libsanitizer/tsan/tsan_interface_java.cpp b/libsanitizer/tsan/tsan_interface_java.cpp index 7d3d32f..081c6ff 100644 --- a/libsanitizer/tsan/tsan_interface_java.cpp +++ b/libsanitizer/tsan/tsan_interface_java.cpp @@ -19,7 +19,7 @@ #include "sanitizer_common/sanitizer_stacktrace.h" #include "sanitizer_common/sanitizer_procmaps.h" -using namespace __tsan; // NOLINT +using namespace __tsan; const jptr kHeapAlignment = 8; diff --git a/libsanitizer/tsan/tsan_interface_java.h b/libsanitizer/tsan/tsan_interface_java.h index 93e67bd..51b4452 100644 --- a/libsanitizer/tsan/tsan_interface_java.h +++ b/libsanitizer/tsan/tsan_interface_java.h @@ -31,7 +31,7 @@ extern "C" { #endif -typedef unsigned long jptr; // NOLINT +typedef unsigned long jptr; // Must be called before any other callback from Java. void __tsan_java_init(jptr heap_begin, jptr heap_size) INTERFACE_ATTRIBUTE; diff --git a/libsanitizer/tsan/tsan_md5.cpp b/libsanitizer/tsan/tsan_md5.cpp index d146e1c..72857b7 100644 --- a/libsanitizer/tsan/tsan_md5.cpp +++ b/libsanitizer/tsan/tsan_md5.cpp @@ -29,7 +29,7 @@ namespace __tsan { SET(n) typedef unsigned int MD5_u32plus; -typedef unsigned long ulong_t; // NOLINT +typedef unsigned long ulong_t; typedef struct { MD5_u32plus lo, hi; diff --git a/libsanitizer/tsan/tsan_mman.h b/libsanitizer/tsan/tsan_mman.h index 467aabd..a5280d4 100644 --- a/libsanitizer/tsan/tsan_mman.h +++ b/libsanitizer/tsan/tsan_mman.h @@ -79,11 +79,10 @@ enum MBlockType { void *internal_alloc(MBlockType typ, uptr sz); void internal_free(void *p); -template<typename T> -void DestroyAndFree(T *&p) { +template <typename T> +void DestroyAndFree(T *p) { p->~T(); internal_free(p); - p = 0; } } // namespace __tsan diff --git a/libsanitizer/tsan/tsan_new_delete.cpp b/libsanitizer/tsan/tsan_new_delete.cpp index 3ed3c84..fc44a52 100644 --- a/libsanitizer/tsan/tsan_new_delete.cpp +++ b/libsanitizer/tsan/tsan_new_delete.cpp @@ -17,7 +17,7 @@ #include "tsan_interceptors.h" #include "tsan_rtl.h" -using namespace __tsan; // NOLINT +using namespace __tsan; namespace std { struct nothrow_t {}; diff --git a/libsanitizer/tsan/tsan_platform.h b/libsanitizer/tsan/tsan_platform.h index 0d106c4..63eb14f 100644 --- a/libsanitizer/tsan/tsan_platform.h +++ b/libsanitizer/tsan/tsan_platform.h @@ -457,6 +457,8 @@ struct Mapping47 { static const uptr kAppMemEnd = 0x00e000000000ull; }; +#define TSAN_RUNTIME_VMA 1 + #elif SANITIZER_GO && defined(__aarch64__) /* Go on linux/aarch64 (48-bit VMA) diff --git a/libsanitizer/tsan/tsan_report.cpp b/libsanitizer/tsan/tsan_report.cpp index 655aa5f..368f1ca 100644 --- a/libsanitizer/tsan/tsan_report.cpp +++ b/libsanitizer/tsan/tsan_report.cpp @@ -298,7 +298,7 @@ static bool FrameIsInternal(const SymbolizedStack *frame) { const char *file = frame->info.file; const char *module = frame->info.module; if (file != 0 && - (internal_strstr(file, "tsan_interceptors.cpp") || + (internal_strstr(file, "tsan_interceptors_posix.cpp") || internal_strstr(file, "sanitizer_common_interceptors.inc") || internal_strstr(file, "tsan_interface_"))) return true; diff --git a/libsanitizer/tsan/tsan_rtl.cpp b/libsanitizer/tsan/tsan_rtl.cpp index 1ac3907..3f3c0cc 100644 --- a/libsanitizer/tsan/tsan_rtl.cpp +++ b/libsanitizer/tsan/tsan_rtl.cpp @@ -239,6 +239,15 @@ void DontNeedShadowFor(uptr addr, uptr size) { ReleaseMemoryPagesToOS(MemToShadow(addr), MemToShadow(addr + size)); } +#if !SANITIZER_GO +void UnmapShadow(ThreadState *thr, uptr addr, uptr size) { + if (size == 0) return; + DontNeedShadowFor(addr, size); + ScopedGlobalProcessor sgp; + ctx->metamap.ResetRange(thr->proc(), addr, size); +} +#endif + void MapShadow(uptr addr, uptr size) { // Global data is not 64K aligned, but there are no adjacent mappings, // so we can get away with unaligned mapping. @@ -329,7 +338,7 @@ static void CheckShadowMapping() { #if !SANITIZER_GO static void OnStackUnwind(const SignalContext &sig, const void *, BufferedStackTrace *stack) { - stack->Unwind(sig.pc, sig.bp, sig.context, + stack->Unwind(StackTrace::GetNextInstructionPc(sig.pc), sig.bp, sig.context, common_flags()->fast_unwind_on_fatal); } @@ -987,6 +996,14 @@ void MemoryRangeImitateWrite(ThreadState *thr, uptr pc, uptr addr, uptr size) { MemoryRangeSet(thr, pc, addr, size, s.raw()); } +void MemoryRangeImitateWriteOrResetRange(ThreadState *thr, uptr pc, uptr addr, + uptr size) { + if (thr->ignore_reads_and_writes == 0) + MemoryRangeImitateWrite(thr, pc, addr, size); + else + MemoryResetRange(thr, pc, addr, size); +} + ALWAYS_INLINE USED void FuncEntry(ThreadState *thr, uptr pc) { StatInc(thr, StatFuncEnter); diff --git a/libsanitizer/tsan/tsan_rtl.h b/libsanitizer/tsan/tsan_rtl.h index 3a8231b..c38fc43 100644 --- a/libsanitizer/tsan/tsan_rtl.h +++ b/libsanitizer/tsan/tsan_rtl.h @@ -238,7 +238,7 @@ class Shadow : public FastState { unsigned kS2AccessSize) { bool res = false; u64 diff = s1.addr0() - s2.addr0(); - if ((s64)diff < 0) { // s1.addr0 < s2.addr0 // NOLINT + if ((s64)diff < 0) { // s1.addr0 < s2.addr0 // if (s1.addr0() + size1) > s2.addr0()) return true; if (s1.size() > -diff) res = true; @@ -680,6 +680,7 @@ void ALWAYS_INLINE StatSet(ThreadState *thr, StatType typ, u64 n) { void MapShadow(uptr addr, uptr size); void MapThreadTrace(uptr addr, uptr size, const char *name); void DontNeedShadowFor(uptr addr, uptr size); +void UnmapShadow(ThreadState *thr, uptr addr, uptr size); void InitializeShadowMemory(); void InitializeInterceptors(); void InitializeLibIgnore(); @@ -759,6 +760,8 @@ void ALWAYS_INLINE MemoryWriteAtomic(ThreadState *thr, uptr pc, void MemoryResetRange(ThreadState *thr, uptr pc, uptr addr, uptr size); void MemoryRangeFreed(ThreadState *thr, uptr pc, uptr addr, uptr size); void MemoryRangeImitateWrite(ThreadState *thr, uptr pc, uptr addr, uptr size); +void MemoryRangeImitateWriteOrResetRange(ThreadState *thr, uptr pc, uptr addr, + uptr size); void ThreadIgnoreBegin(ThreadState *thr, uptr pc, bool save_stack = true); void ThreadIgnoreEnd(ThreadState *thr, uptr pc); diff --git a/libsanitizer/tsan/tsan_rtl_ppc64.S b/libsanitizer/tsan/tsan_rtl_ppc64.S index 9e533a7..8285e21 100644 --- a/libsanitizer/tsan/tsan_rtl_ppc64.S +++ b/libsanitizer/tsan/tsan_rtl_ppc64.S @@ -1,6 +1,5 @@ #include "tsan_ppc_regs.h" - .machine altivec .section .text .hidden __tsan_setjmp .globl _setjmp diff --git a/libsanitizer/tsan/tsan_rtl_report.cpp b/libsanitizer/tsan/tsan_rtl_report.cpp index 47b8bf7..949beac 100644 --- a/libsanitizer/tsan/tsan_rtl_report.cpp +++ b/libsanitizer/tsan/tsan_rtl_report.cpp @@ -27,7 +27,7 @@ namespace __tsan { -using namespace __sanitizer; // NOLINT +using namespace __sanitizer; static ReportStack *SymbolizeStack(StackTrace trace); @@ -154,6 +154,7 @@ ScopedReportBase::ScopedReportBase(ReportType typ, uptr tag) { ScopedReportBase::~ScopedReportBase() { ctx->report_mtx.Unlock(); DestroyAndFree(rep_); + rep_ = nullptr; } void ScopedReportBase::AddStack(StackTrace stack, bool suppressable) { @@ -700,7 +701,7 @@ void ReportRace(ThreadState *thr) { rep.AddLocation(addr_min, addr_max - addr_min); #if !SANITIZER_GO - { // NOLINT + { Shadow s(thr->racy_state[1]); if (s.epoch() <= thr->last_sleep_clock.get(s.tid())) rep.AddSleep(thr->last_sleep_stack_id); diff --git a/libsanitizer/tsan/tsan_suppressions.cpp b/libsanitizer/tsan/tsan_suppressions.cpp index 6bf6720..a1c1bf8 100644 --- a/libsanitizer/tsan/tsan_suppressions.cpp +++ b/libsanitizer/tsan/tsan_suppressions.cpp @@ -50,7 +50,7 @@ static const char *kSuppressionTypes[] = { void InitializeSuppressions() { CHECK_EQ(nullptr, suppression_ctx); - suppression_ctx = new (suppression_placeholder) // NOLINT + suppression_ctx = new (suppression_placeholder) SuppressionContext(kSuppressionTypes, ARRAY_SIZE(kSuppressionTypes)); suppression_ctx->ParseFromFile(flags()->suppressions); #if !SANITIZER_GO |