61

我添加了 AddressSanitizer 标志如下:

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

使用Unix Makefiles.

问题出现在生成 Xcode 项目时,它只是不想链接,因为它找不到 ASan 库。

我已经找到了两个解决方案,但决定不使用它们,因为它们不能仅使用 CMake 实现自动化:

  1. 添加-Wl,-undefined,dynamic_lookup到链接标志,因此它跳过链接到动态库。
  2. 直接链接libclang_rt.asan_osx_dynamic.dylib

那么这两种解决方案有什么问题呢?

  • 使用解决方案 #1 时,我必须在 Xcode 中手动打开目标方案并添加DYLD_INSERT_LIBRARIES指向libclang_rt.asan_osx_dynamic.dylib.
  • 使用解决方案 #2 时,ASan 库的路径因计算机而异。

此外,作为另一种解决方案,我尝试从 Xcode 目标方案中启用 Address Sanitizer 标志,但有趣的是它没有检测到我添加的问题,因此我没有将其列为解决方案,因为它未能通过我的测试。

任何帮助都感激不尽。

4

7 回答 7

36

您还需要向链接器提供标志。我这样做是这样的:

set (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fno-omit-frame-pointer -fsanitize=address")
set (CMAKE_LINKER_FLAGS_DEBUG "${CMAKE_LINKER_FLAGS_DEBUG} -fno-omit-frame-pointer -fsanitize=address")
于 2017-08-29T13:22:06.933 回答
16

由于这些天投票率最高的答案是错误的方法,而且我没有得到正确的 cmake 解决方案来阅读这个线程,我想我会在写这篇文章时提到正确的方法,以便下一位读者这样做不需要花太多时间。希望能帮助到你。

此解决方案的想法是传递-fsanitize=address给编译器和链接器标志。

如果您想同时为所有目标启用此功能,可以使用add_compile_optionsadd_link_options。如果您有多个,可能是大量的目标,这是有道理的。

add_compile_options(-fsanitize=address)
add_link_options(-fsanitize=address)

或者,您也可以使用target_compile_optionstarget_link_options为特定目标设置这些。如果您不希望这适用于所有目标,这可能更有意义。

target_compile_options(asan-target PRIVATE -fsanitize=address)
target_link_options(asan-target PRIVATE -fsanitize=address)
于 2021-12-08T08:46:54.633 回答
12

我建议创建您自己的 Asan 个人资料。

get_property(isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)

if(isMultiConfig)
    if(NOT "Asan" IN_LIST CMAKE_CONFIGURATION_TYPES)
        list(APPEND CMAKE_CONFIGURATION_TYPES Asan)
    endif()
else()
    set(allowedBuildTypes Asan Debug Release RelWithDebInfo MinSizeRel)
    set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "${allowedBuildTypes}")

    if(CMAKE_BUILD_TYPE AND NOT CMAKE_BUILD_TYPE IN_LIST allowedBuildTypes)
        message(FATAL_ERROR "Invalid build type: ${CMAKE_BUILD_TYPE}")
    endif()
endif()

set(CMAKE_C_FLAGS_ASAN
    "${CMAKE_C_FLAGS_DEBUG} -fsanitize=address -fno-omit-frame-pointer" CACHE STRING
    "Flags used by the C compiler for Asan build type or configuration." FORCE)

set(CMAKE_CXX_FLAGS_ASAN
    "${CMAKE_CXX_FLAGS_DEBUG} -fsanitize=address -fno-omit-frame-pointer" CACHE STRING
    "Flags used by the C++ compiler for Asan build type or configuration." FORCE)

set(CMAKE_EXE_LINKER_FLAGS_ASAN
    "${CMAKE_SHARED_LINKER_FLAGS_DEBUG} -fsanitize=address" CACHE STRING
    "Linker flags to be used to create executables for Asan build type." FORCE)

set(CMAKE_SHARED_LINKER_FLAGS_ASAN
    "${CMAKE_SHARED_LINKER_FLAGS_DEBUG} -fsanitize=address" CACHE STRING
    "Linker lags to be used to create shared libraries for Asan build type." FORCE)

笔记:

  1. 带有 MSVC 的 Windows 的 AddressSanitizer (ASan) 处于实验阶段,因此我没有在这里提供 MSVC 方式。

  2. CMAKE_BUILD_TYPE不被多配置生成器(Xcode、Visual Studio 等)使用,因此我首先提供了一个示例来检查这一点。

  3. 的默认值为CMAKE_BUILD_TYPE字符串。并且用户可以CMAKE_BUILD_TYPE在 cmake 命令行中设置为任何值。因此,我们检查这两种情况,并确保我们正在处理已知的构建类型(如果提供)。

  4. 还有CMAKE_MODULE_LINKER_FLAGS你可能想要配置的。

用法:

$ cmake \
    -DCMAKE_BUILD_TYPE=Asan \
    ...
    ...
于 2020-10-10T15:01:32.810 回答
11

cmake 3.13
引入xcode 模式的配置

在 CMake 中

cmake_minimum_required(VERSION 3.13)
set(CMAKE_XCODE_GENERATE_SCHEME ON)
set(CMAKE_XCODE_SCHEME_ADDRESS_SANITIZER ON)
set(CMAKE_XCODE_SCHEME_ADDRESS_SANITIZER_USE_AFTER_RETURN ON)

何时构建

xcodebuild -enableAddressSanitizer YES
于 2018-11-15T07:24:52.200 回答
3

首先确保使用调试信息,例如设置CMAKE_BUILD_TYPEDebug.

然后,如果您的目标是可执行文件或共享库,那么您可以设置这些 cmake 变量:

  • CMAKE_EXE_LINKER_FLAGS
  • CMAKE_EXE_LINKER_FLAGS_DEBUG
  • CMAKE_SHARED_LINKER_FLAGS
  • CMAKE_SHARED_LINKER_FLAGS_DEBUG

即当您的目标是可执行文件时:

set(CMAKE_BUILD_TYPE "Debug")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_LINKER_FLAGS_DEBUG} -fno-omit-frame-pointer -fsanitize=address")

当您的目标是共享库时:

set(CMAKE_BUILD_TYPE "Debug")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS_DEBUG} -fno-omit-frame-pointer -fsanitize=address")

但是,当您的可执行文件依赖于静态库并且您想使用 asan 来检查您的静态库时,您必须像这样设置:

set(CMAKE_BUILD_TYPE "Debug")
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -fno-omit-frame-pointer -fsanitize=address")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fno-omit-frame-pointer -fsanitize=address")
set(CMAKE_LINKER_FLAGS_DEBUG "${CMAKE_LINKER_FLAGS_DEBUG} -fno-omit-frame-pointer -fsanitize=address")
于 2020-11-26T09:20:38.360 回答
2

我目前找到的最简单的解决方案是

cmake -DCMAKE_BUILD_TYPE=ASAN .

我更喜欢这个选项,因为它表达了意图(运行消毒剂)而不是修改许多标志。

我不知道这个选项是什么时候添加的。我也找不到任何文档。

于 2019-04-29T21:45:13.667 回答
0

我发现其他答案不起作用,您需要在工具链文件中设置初始化变量:

set(CMAKE_EXE_LINKER_FLAGS_INIT "-fsanitize=address -fno-omit-frame-pointer")
于 2020-11-03T13:01:36.903 回答