1

I download normally the latest clang version from their website. This helps me use the latest version of C++ as doing this with gcc is not really possible. I just get the binaries for my Ubuntu/Debian and I'm good to go.

For me, linking with tsan library (thread-sanitizer library) has never been something simple. I use insane measures in cmake to make it work. Previously, when I used gcc from the system, this is what I did in cmake to make the link work correctly:

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=thread -ltsan")
set(CMAKE_LINK_LIBRARY_FLAG "-ltsan -l")

which basically modifies the linking flags to link every little thing with tsan. This has worked fine for a while, but to make it work, I should use gcc, the system's compiler. If I try to link like this with clang 7, I get a segfault when I run my program.

So I searched for the available tsan libraries that come with clang, and here's what I found:

user@machine:/opt/clang7$ find -iname "*tsan*"
./lib/clang/7.0.0/lib/linux/libclang_rt.tsan_cxx-x86_64.a
./lib/clang/7.0.0/lib/linux/libclang_rt.tsan-x86_64.a
./lib/clang/7.0.0/lib/linux/libclang_rt.tsan_cxx-x86_64.a.syms
./lib/clang/7.0.0/lib/linux/libclang_rt.tsan-x86_64.a.syms
./lib/clang/7.0.0/include/sanitizer/tsan_interface_atomic.h
./lib/clang/7.0.0/include/sanitizer/tsan_interface.h

There seems to be tsan libraries there. I guess I gotta link to them. How do I do that?

This, doesn't seem to work:

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=thread -L/opt/clang7/lib/clang/7.0.0/lib/linux/ -lclang_rt.tsan_cxx-x86_64")
set(CMAKE_LINK_LIBRARY_FLAG "-L/opt/clang7/lib/clang/7.0.0/lib/linux/ -lclang_rt.tsan_cxx-x86_64 -l")

This doesn't work either:

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=thread -l:/opt/clang7/lib/clang/7.0.0/lib/linux/libclang_rt.tsan_cxx-x86_64.a")
set(CMAKE_LINK_LIBRARY_FLAG "-l:/opt/clang7/lib/clang/7.0.0/lib/linux/libclang_rt.tsan_cxx-x86_64.a -l")

I've tried a few other combinations. But None of them seem to work. The errors I get are either linking errors or undefined references to some tsan components.

How can I link to tsan from the newest clang's prebuilt binaries?

The Quantum Physicist
  • 24,987
  • 19
  • 103
  • 189

1 Answers1

1

Setting the link flag for the compilation is a big no-no:

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=thread")

Then you need to do the same for the link flags as well:

SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=thread") 
SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -fsanitize=thread")

You can also change the target properties only:

set_target_properties(${TARGET} PROPERTIES
    LINK_FLAGS -fsanitizer=thread
    COMPILE_FLAGS -fsanitizer=thread)

Be aware that this overrides all flags (I don't remember if CMAKE_CXX_FLAGS are also there, maybe not), you may want to retrieve the current ones and append these instead of removing everything.

clang knows where its support libraries for sanitation are (as you said, these are tagged with a triple-like information and are not in the usual library folders, to avoid any contamination from other installs), and the full fsanitize=tsan flag will make it pick up these versions. Note that it's not -ltsan, but a full option that will make clang pick up the proper backend in the path where its own sanitizers are.

The Quantum Physicist
  • 24,987
  • 19
  • 103
  • 189
Matthieu Brucher
  • 21,634
  • 7
  • 38
  • 62
  • Somehow when I do this it ruins other packages for me... I'm still trying to get it to work. Boost::thread is getting wrecked with this. Cmake says: "Could NOT find Threads (missing: Threads_FOUND) ". Are you sure there are no other necessary flags? I reproducibly removed these flags and restored them to create the problem. – The Quantum Physicist Dec 21 '18 at 10:28
  • Oh, OK, fair enough. I'll add the target specific version to my answer. – Matthieu Brucher Dec 21 '18 at 10:34
  • But doesn't this mean it won't link to tsan for everything? I'm lost on why this breaks with the threads library and how this gets fixed. The weird link flag change I did was to make the whole project use tsan. I kinda wanted this to be global. – The Quantum Physicist Dec 21 '18 at 10:39
  • The first option will use tsan for everything, even detecting a library, which could be problematic (see the CMake output log and error log in the CMakeFiles folder). The second one will only activate tsan for the libraries you want to sanitize. – Matthieu Brucher Dec 21 '18 at 10:44
  • Are you sure you didn't mistype `-fsanitize=tsan` as it should've been `-fsanitize=thread`? – The Quantum Physicist Dec 21 '18 at 10:45
  • OK it works fine with `-fsanitize=thread`. Nothing to do with the target. Please correct your answer. There's also quotes imbalance. Thanks for the help :-) – The Quantum Physicist Dec 21 '18 at 10:51
  • Instead of setting both link and compile flags for the target, it's possible to do both at once using `target_link_libraries(${TARGET} PRIVATE -fsanitize=thread)`. Source: https://stackoverflow.com/a/50163972/8366223 – PolyGlot Jan 13 '21 at 16:04