【问题标题】:How can I link to thread sanitizer with a newer version of clang than the system provides?如何使用比系统提供的更新版本的 clang 链接到线程清理程序?
【发布时间】:2018-12-21 10:01:27
【问题描述】:

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

对我来说,与 tsan 库(线程清理库)链接从来都不是一件简单的事情。我在 cmake 中使用了疯狂的措施来使其工作。以前,当我从系统中使用 gcc 时,这是我在 cmake 中所做的以使链接正常工作:

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

它基本上修改了链接标志以将每个小东西与tsan 链接。这已经工作了一段时间,但要让它工作,我应该使用系统的编译器 gcc。如果我尝试像这样与 clang 7 链接,则在运行程序时会出现段错误。

于是我搜索了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 图书馆。我想我必须链接到他们。我该怎么做?

这似乎不起作用:

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

我尝试了其他几种组合。但它们似乎都不起作用。我得到的错误要么是链接错误,要么是对某些 tsan 组件的未定义引用。

如何从最新的 clang 的预构建二进制文件链接到 tsan?

【问题讨论】:

  • this doesn't work either 是什么意思?
  • 您是否正确设置了链接标志?你所拥有的肯定是错误的。 SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=tsan) SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -fsanitize=tsan)
  • @MatthieuBrucher 正如我所提到的,我得到链接器错误或对某些 tsan 组件的未定义引用。
  • @MatthieuBrucher 即使这样可行,也将使用较旧的库。我需要链接到 clang 7 的 tsan 库。不是系统中的那个。
  • 你为什么说即使这行得通?这才是正确的链接方式。如果订单有问题,请使用 VERBOSE=1 make 和 -v 表示详细程度。

标签: c++ thread-safety clang c++14 thread-sanitizer


【解决方案1】:

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

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

那么你也需要对链接标志做同样的事情:

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 flag 将使它拾取这些版本。请注意,它不是 -ltsan,而是一个完整的选项,它可以让 clang 在它自己的 sanitizer 所在的路径中选择正确的后端。

【讨论】:

  • 不知何故,当我这样做时,它会破坏我的其他软件包......我仍在努力让它工作。 Boost::thread 正在被这个破坏。 Cmake 说:“找不到线程(缺少:Threads_FOUND)”。你确定没有其他必要的标志吗?我重复地删除了这些标志并恢复它们以产生问题。
  • 哦,好吧,很公平。我会将目标特定版本添加到我的答案中。
  • 但这是否意味着它不会链接到 tsan 的所有内容?我不知道为什么这会与线程库中断以及如何解决这个问题。我所做的奇怪的链接标志更改是让整个项目使用 tsan。我有点希望这是全球性的。
  • 第一个选项将对所有内容使用 tsan,甚至检测库,这可能会出现问题(请参阅 CMakeFiles 文件夹中的 CMake 输出日志和错误日志)。第二个只会为您要清理的库激活 tsan。
  • 你确定你没有输入错误的-fsanitize=tsan,因为它应该是-fsanitize=thread
猜你喜欢
  • 2021-12-22
  • 2018-04-04
  • 2011-05-01
  • 2012-02-03
  • 2015-07-17
  • 2018-01-27
  • 1970-01-01
  • 1970-01-01
  • 2020-08-28
相关资源
最近更新 更多