looks like it is not possible to use -fsanitize=thread with current trunk. > cat test.c int main() { return 0; } > gcc -fsanitize=thread -pie -fPIC test.c /data/vjoost/gnu/gcc_trunk/install/lib/gcc/x86_64-unknown-linux-gnu/4.9.0/../../../../lib64/libtsan.so: undefined reference to `sigsetjmp' collect2: error: ld returned 1 exit status
Interesting. tsan in clang works, so we either have problems in the gcc build system or we have some differences in the code that affect the sigsetjmp interceptor. one other problem would be that we have zero tests for tsan in gcc :(
glibc (at least the 2.17 I have around) doesn't have sigsetjmp function at all, it only conditionally has sigsetjmp as a macro: #ifdef __USE_POSIX ... /* Store the calling environment in ENV, also saving the signal mask if SAVEMASK is nonzero. Return 0. */ # define sigsetjmp(env, savemask) __sigsetjmp (env, savemask) ... #endif so extern "C" int setjmp(void *env); extern "C" int _setjmp(void *env); extern "C" int sigsetjmp(void *env); extern "C" int __sigsetjmp(void *env); DEFINE_REAL(int, setjmp, void *env) DEFINE_REAL(int, _setjmp, void *env) DEFINE_REAL(int, sigsetjmp, void *env) DEFINE_REAL(int, __sigsetjmp, void *env) is just asking for trouble. Not to mention that the arguments are wrong even for __sigsetjmp, which has two arguments rather than just one. So, if it works with clang, must be purely by accident, perhaps the difference is that __USE_POSIX is defined in one case and not in the other one, or something, but still, it can't really work in either case.
Hi, Can you please try the following patch? If it does not work, please check what else references sigsetjmp. --- rtl/tsan_interceptors.cc (revision 194823) +++ rtl/tsan_interceptors.cc (working copy) @@ -2034,6 +2034,9 @@ Die(); } +extern "C" uptr dlsym(uptr, const char*); +const uptr RTLD_NEXT = -1; + void InitializeInterceptors() { CHECK_GT(cur_thread()->in_rtl, 0); @@ -2048,10 +2051,11 @@ SANITIZER_COMMON_INTERCEPTORS_INIT; - TSAN_INTERCEPT(setjmp); - TSAN_INTERCEPT(_setjmp); - TSAN_INTERCEPT(sigsetjmp); - TSAN_INTERCEPT(__sigsetjmp); + *(uptr*)&REAL(setjmp) = dlsym(RTLD_NEXT, "setjmp"); + *(uptr*)&REAL(_setjmp) = dlsym(RTLD_NEXT, "_setjmp"); + *(uptr*)&REAL(sigsetjmp) = dlsym(RTLD_NEXT, "sigsetjmp"); + *(uptr*)&REAL(__sigsetjmp) = dlsym(RTLD_NEXT, "__sigsetjmp"); + TSAN_INTERCEPT(longjmp); TSAN_INTERCEPT(siglongjmp);
> glibc (at least the 2.17 I have around) doesn't have sigsetjmp function at all this must be fine, we do not call it if it's not used > Not to mention that the arguments are wrong even for __sigsetjmp setjmp interception is a bit tricky (because one can't wrap libc setjmp into another function, otherwise the saved context will be broken) so it's actually called from tsan_rtl_amd64.S by a tail call here: // tail jump to libc sigsetjmp movl $0, %eax movq _ZN14__interception16real___sigsetjmpE@GOTPCREL(%rip), %rdx jmp *(%rdx) .cfi_endproc .size __sigsetjmp, .-__sigsetjmp
(In reply to Dmitry Vyukov from comment #3) > Can you please try the following patch compiles with warnings: ../../../../gcc/libsanitizer/tsan/tsan_interceptors.cc:2022:12: note: in expansion of macro ‘REAL’ *(uptr*)&REAL(_setjmp) = dlsym(RTLD_NEXT, "_setjmp"); ^ ../../../../gcc/libsanitizer/interception/interception.h:145:25: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing] However, it fixes the issue mentioned.
Great, thanks! I will prepare a real patch.
I've committed the fix into llvm: http://llvm.org/viewvc/llvm-project?view=revision&revision=195345
(In reply to Kostya Serebryany from comment #1) > one other problem would be that we have zero tests for tsan in gcc :( It would be great if someone could do something about that, even just a single test would have shown this problem, which I think has been there for at least a week.
Fixed (works for me now).
(In reply to Richard Biener from comment #9) > Fixed unlikely, the fix only went to the llvm repo so far. > (works for me now). depends on your libc
planing next merge from llvm to gcc in ~1 week.
(In reply to Kostya Serebryany from comment #11) > planing next merge from llvm to gcc in ~1 week. Fixed in current trunk. Thanks!