在CMake中启用AddressSanitizer并使其在Xcode中工作的正确方法是什么

bnl4lu3b  于 2023-02-19  发布在  其他
关注(0)|答案(7)|浏览(251)

我已添加AddressSanitizer标志,如下所示:

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

在使用Unix Makefiles时,一切都构建和运行良好。
问题出现在生成Xcode项目时,它只是不想链接,因为它找不到ASan库。
我已经找到了两个解决方案,但决定不使用它们,因为它们不能仅使用CMake自动化:
1.将-Wl,-undefined,dynamic_lookup添加到链接的标志,这样它就跳过了到动态库的链接。
1.直接与libclang_rt.asan_osx_dynamic.dylib链接。
那么这两种解决方案的问题是什么呢?

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

此外,作为另一个解决方案,我尝试从Xcode目标方案中启用地址过滤器标志,但有趣的是,它没有检测到我添加的问题,所以我没有将其列为解决方案,因为它没有通过我的测试。
任何帮助都将不胜感激。

to94eoyn

to94eoyn1#

由于得票最多的答案是错误的方式做这几天,我没有得到适当的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)
gywdnpxw

gywdnpxw2#

你也需要为链接器提供标志。我是这样做的:

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

rjee0c153#

我建议你建立你自己的峨山档案。

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. AddressSanitizer(ASan)的Windows与MSVC是在实验阶段,因此我没有提供MSVC的方式在这里。
    1.多配置生成器(Xcode、Visual Studio等)不使用CMAKE_BUILD_TYPE,因此我首先提供了一个示例来检查这一点。
  2. CMAKE_BUILD_TYPE的默认值是一个 * 空字符串 *。用户可以在cmake命令行将CMAKE_BUILD_TYPE设置为任何值。因此,我们检查这两种情况,并确保我们正在处理一个已知的构建类型(如果提供)。
    1.您可能还需要配置CMAKE_MODULE_LINKER_FLAGS
    • 用法:**
$ cmake \
    -DCMAKE_BUILD_TYPE=Asan \
    ...
    ...
pdsfdshx

pdsfdshx4#

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
falq053o

falq053o5#

首先确保调试信息,例如将CMAKE_BUILD_TYPE设置为Debug,传递GCC/Clang的-g标志。
然后,如果你的目标是一个可执行文件或共享库,那么你可以设置这些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")
whlutmcx

whlutmcx6#

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

cmake -DCMAKE_BUILD_TYPE=ASAN .

我更喜欢这个选项,因为它表达了意图(运行杀毒程序),而不是修改大量的标志。
我不知道这个选项是什么时候添加的。我也找不到它的任何文档。

vnjpjtjt

vnjpjtjt7#

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

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

相关问题