diff --git a/compiler-rt/lib/tsan/rtl/tsan_interceptors.h b/compiler-rt/lib/tsan/rtl/tsan_interceptors.h index 3886a30cd88d1..61dbb81ffec43 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_interceptors.h +++ b/compiler-rt/lib/tsan/rtl/tsan_interceptors.h @@ -43,9 +43,26 @@ inline bool in_symbolizer() { ScopedInterceptor si(thr, #func, GET_CALLER_PC()); \ UNUSED const uptr pc = GET_CURRENT_PC(); +#ifdef __powerpc64__ +// Debugging of crashes on powerpc after commit: +// c80604f7a3 ("tsan: remove real func check from interceptors") +// Somehow replacing if with DCHECK leads to strange failures in: +// SanitizerCommon-tsan-powerpc64le-Linux :: Linux/ptrace.cpp +// https://lab.llvm.org/buildbot/#/builders/105 +// https://lab.llvm.org/buildbot/#/builders/121 +// https://lab.llvm.org/buildbot/#/builders/57 +# define CHECK_REAL_FUNC(func) \ + if (REAL(func) == 0) { \ + Report("FATAL: ThreadSanitizer: failed to intercept %s\n", #func); \ + Die(); \ + } +#else +# define CHECK_REAL_FUNC(func) DCHECK(REAL(func)) +#endif + #define SCOPED_TSAN_INTERCEPTOR(func, ...) \ SCOPED_INTERCEPTOR_RAW(func, __VA_ARGS__); \ - DCHECK(REAL(func)); \ + CHECK_REAL_FUNC(func); \ if (!thr->is_inited || thr->ignore_interceptors || thr->in_ignored_lib) \ return REAL(func)(__VA_ARGS__); diff --git a/compiler-rt/test/sanitizer_common/TestCases/Linux/ptrace.cpp b/compiler-rt/test/sanitizer_common/TestCases/Linux/ptrace.cpp index 82532c35fab5e..a2d32439e5003 100644 --- a/compiler-rt/test/sanitizer_common/TestCases/Linux/ptrace.cpp +++ b/compiler-rt/test/sanitizer_common/TestCases/Linux/ptrace.cpp @@ -3,15 +3,16 @@ // UNSUPPORTED: android #include +#include #include #include +#include #include #include +#include #include #include -#include #include -#include #if __mips64 || __arm__ #include #include @@ -46,9 +47,14 @@ int main(void) { #endif // __x86_64__ #if (__powerpc64__ || __mips64 || __arm__) - struct pt_regs regs; + // Check that nothing writes out-of-bounds. + struct pt_regs regs_buf[4]; + memset(®s_buf, 0xcd, sizeof(regs_buf)); + struct pt_regs ®s = regs_buf[1]; res = ptrace((enum __ptrace_request)PTRACE_GETREGS, pid, NULL, ®s); assert(!res); + assert(memcmp(®s_buf[0], ®s_buf[3], sizeof(regs_buf[3])) == 0); + assert(memcmp(®s_buf[2], ®s_buf[3], sizeof(regs_buf[3])) == 0); #if (__powerpc64__) if (regs.nip) printf("%lx\n", regs.nip);