我如何 link 使用比系统提供的更新版本的 clang 线程消毒器?

How can I link to thread sanitizer with a newer version of clang than the system provides?

我从their website正常下载最新的clang版本。这有助于我使用最新版本的 C++,因为用 gcc 这样做是不可能的。我刚刚获得 Ubuntu/Debian 的二进制文件,我很高兴。

对我来说,link使用 tsan 库(thread-sanitizer 库)从来都不是一件简单的事情。我在 cmake 中使用疯狂的措施来让它工作。以前,当我从系统中使用 gcc 时,这是我在 cmake 中为使 link 正常工作所做的:

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

基本上将 linking 标志修改为 link 每个带有 tsan 的小东西。这在一段时间内运行良好,但要使其运行,我应该使用系统的编译器 gcc。如果我尝试使用 clang 7 像这样 link,我会在 运行 我的程序时遇到段错误。

所以我搜索了 clang 附带的可用 tsan 库,这是我找到的:

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

那里好像有tsan图书馆。我想我得 link 给他们。我该怎么做?

这个,好像不行:

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")

这也不行:

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")

我尝试了其他几种组合。但其中 None 似乎有效。我得到的错误是 linking 错误或对某些 tsan 组件的未定义引用。

我如何link从最新的 clang 预构建二进制文件中进行 tsan?

为编译设置 link 标志是一个很大的禁忌:

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

然后你需要对 link 标志做同样的事情:

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

您也可以仅更改目标属性:

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

请注意,这会覆盖所有标志(我不记得 CMAKE_CXX_FLAGS 是否也存在,也许不存在),您可能想要检索当前的标志并附加这些标志,而不是删除所有标志。

clang 知道它的卫生支持库在哪里(正如你所说,这些库带有类似三重信息的标记,并且不在通常的库文件夹中,以避免其他安装造成任何污染),以及完整的 fsanitize=tsan 标志将使它选择这些版本。请注意,它不是 -ltsan,而是一个完整的选项,可以让 clang 在它自己的消毒剂所在的路径中选择正确的后端。