在 Xcode 中工作的 CMake 中启用地址清理器的正确方法是什么



我已经添加了addressSanitizer flag如下:

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目标方案启用地址消毒剂标志,但有趣的是,它没有检测到我添加的问题,因此我没有将其列为解决方案,因为它使我的测试失败了。

任何帮助都将不胜感激。

,因为最高投票的答案是这些天的错误方法,而我没有为此读取此线程提供适当的cmake解决方案,我想我想提到正确的方法写这篇文章的时间,以便下一个读者不需要花费太多时间。

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

如果您想同时启用所有目标,则可以使用add_compile_options和add_link_options。如果您有多个(可能是大的目标(,这是有道理的。

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

另外,您也可以使用target_compile_options和target_link_options将其设置为特定目标。如果您不希望它适用于所有目标,这可能会更有意义。

target_compile_options(asan-target PRIVATE -fsanitize=address)
target_link_options(asan-target PRIVATE -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")

我建议创建自己的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_EXE_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的adverseSanitizer(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 
    ...
    ...

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

首先确保使用调试信息,例如

CMAKE_BUILD_TYPE设置为 Debug 传递 -g for gcc/clang。

然后,如果您的目标是可执行文件或共享库,则可以设置这些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")

我当前发现的最简单解决方案是

cmake -DCMAKE_BUILD_TYPE=ASAN .

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

我不知道何时添加此选项。我也找不到任何文档。

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

set(CMAKE_EXE_LINKER_FLAGS_INIT "-fsanitize=address -fno-omit-frame-pointer")

相关内容

最新更新