sanitizers-cmake:用 CMake 为 Fluent Bit 生态目标开启 AddressSanitizer 等动态分析工具

发布时间:2026/11/11 20:30:55

sanitizers-cmake:用 CMake 为 Fluent Bit 生态目标开启 AddressSanitizer 等动态分析工具 sanitizers-cmake用 CMake 为 Fluent Bit 生态目标开启 AddressSanitizer 等动态分析工具【免费下载链接】fluent-bitFast and Lightweight Logs, Metrics and Traces processor for Linux, BSD, OSX and Windows项目地址: https://gitcode.com/GitHub_Trending/fl/fluent-bit导读本文围绕 Fluent Bit 仓库中随 ChunkIO 子项目一同携带的 sanitizers-cmake 说明文档系统讲解如何借助这套 CMake 模块为二进制目标可执行文件与库一键启用 AddressSanitizerASan、MemorySanitizerMSan、ThreadSanitizerTSan与 UndefinedBehaviorSanitizerUBSan。读完本文你将掌握该模块的三种接入方式、四个开关选项的语义与兼容性约束、add_sanitizers()与sanitizer_add_blacklist_file()的用法以及asan-wrapper预加载运行技巧并能结合仓库内 ChunkIO 的CIO_SANITIZE_ADDRESS集成实例把同样的模式复用到自己的 C/C 项目中。一、sanitizers-cmake 是什么sanitizers-cmake 是一个纯粹的 CMake 模块集合核心目标是为 CMake 构建的二进制目标自动追加 sanitizer 编译与链接参数。用户不需要手工往target_compile_options/target_link_options里粘贴-fsanitizeaddress这类标志也不需要为不同编译器维护多套参数全部由模块在配置期探测并注入。在 Fluent Bit 仓库中它被存放在 lib/chunkio/cmake/sanitizers-cmake/ 目录下作为 ChunkIO 子项目的第三方构建工具依赖用于在开启 Address Sanitizer 时给 ChunkIO 的测试与库目标附加 sanitizer 编译能力。该模块以 MIT 协议发布版权归属于 Matthew Arsenault 与亚琛工业大学RWTH Aachen University。模块的文件布局如下目录内共 5 个*.cmake文件加 1 个 shell 包装脚本文件职责FindSanitizers.cmake总入口声明SANITIZE_LINK_STATIC选项统一加载 ASan/TSan/MSan/UBSan 四个子模块定义add_sanitizers()与sanitizer_add_blacklist_file()FindASan.cmakeAddressSanitizer 支持定义SANITIZE_ADDRESS选项与add_sanitize_address()FindTSan.cmakeThreadSanitizer 支持定义SANITIZE_THREAD选项校验平台与位数FindMSan.cmakeMemorySanitizer 支持定义SANITIZE_MEMORY选项校验平台与位数FindUBSan.cmakeUndefinedBehaviorSanitizer 支持定义SANITIZE_UNDEFINED选项sanitize-helpers.cmake内部辅助函数源码语言识别、目标编译器探测、编译器标志探测与注入asan-wrapperASan 预加载包装脚本通过LD_PRELOAD注入 libasantests/自带冒烟测试asan_test 与最短扩展名解析测试二、把模块接入你的项目2.1 方式一Git Submodule 集成官方推荐的做法是把仓库以 submodule 形式挂进自己的工程mkdir externals git submodule add gitgithub.com:arsenm/sanitizers-cmake.git externals/sanitizers-cmake然后把externals/sanitizers-cmake/cmake追加进CMAKE_MODULE_PATHset(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/externals/sanitizers-cmake/cmake ${CMAKE_MODULE_PATH})之后即可在任意 CMakeLists 中直接使用find_package(Sanitizers)2.2 方式二直接拷贝文件如果项目不使用 git 或不想引入 submodule可以直接把 cmake 目录 中的全部文件复制进自己的仓库同样将对应目录加入CMAKE_MODULE_PATH即可。需要注意拷贝方式不会随上游更新需要自行跟进维护。2.3 方式三复用本仓库的现成集成ChunkIO 实例本仓库中的 ChunkIO 项目已经完成了整套接入可以直接当作模板参考。在 lib/chunkio/CMakeLists.txt 中可以看到其集成逻辑option(CIO_SANITIZE_ADDRESS Enable address sanitizer Off) # Check if Address Sanitizer is enabled if(CIO_SANITIZE_ADDRESS OR SANITIZE_ADDRESS) set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/sanitizers-cmake/cmake ${CMAKE_MODULE_PATH}) if(NOT SANITIZE_ADDRESS) add_definitions(-DSANITIZE_ADDRESSOn) endif() find_package(Sanitizers) ... endif()这里揭示了两个实用细节ChunkIO 对外暴露了自有开关CIO_SANITIZE_ADDRESS同时兼容上游的SANITIZE_ADDRESS当只给了前者时通过add_definitions(-DSANITIZE_ADDRESSOn)将其桥接成模块认识的选项。find_package(Sanitizers)之后模块并不定义Sanitizers_FOUND变量这是上游已知问题所以 ChunkIO 改用SANITIZE_LINK_STATIC是否被定义来判断模块是否成功加载未定义则FATAL_ERROR终止已定义则打印 Enabling address sanitizer。从源码结构可以推断SANITIZE_LINK_STATIC在 FindSanitizers.cmake 中被option()声明因此只要模块被加载该变量就一定存在用它作为加载成功的探针是可靠的。三、四个启用开关与各自的约束模块通过四个 CMake 布尔选项控制是否启用对应 sanitizer在配置阶段传入即可cmake -DSANITIZE_ADDRESSOn .. # 地址越界、use-after-free 等内存错误 cmake -DSANITIZE_MEMORYOn .. # 未初始化内存读取 cmake -DSANITIZE_THREADOn .. # 数据竞争 cmake -DSANITIZE_UNDEFINEDOn .. # 未定义行为整数溢出、空指针偏移等也可以配合图形界面ccmake / cmake-gui勾选。3.1 参数探测与平台限制来自源码的事实AddressSanitizerFindASan.cmake的候选标志依次为MSVC 的/fsanitizeaddressClang 3.2 的-g -fsanitizeaddress -fno-omit-frame-pointer保留栈帧便于回溯以及旧式弃用标志-g -faddress-sanitizer。模块会逐个尝试取第一个被当前编译器接受的标志。ThreadSanitizerFindTSan.cmake仅在 Linux 与 macOS 上支持且只支持 64 位系统不满足条件时模块会打印警告并强制把SANITIZE_THREAD置回Off。MemorySanitizerFindMSan.cmake仅支持 Linux 且仅支持 64 位系统其余情况同样警告并关闭。兼容性硬约束ASan 与 TSan、MSan 互不兼容见 FindASan.cmakeTSan 与 MSan 也互不兼容见 FindTSan.cmake组合启用会直接FATAL_ERROR。3.2 编译器不支持时的行为如果编译器没有 sanitizer 能力例如 Intel 编译器模块会在配置期打印警告如WARNING: AddressSanitizer is not available for XXX compiler但CMake 继续执行构建照常进行只是该目标不带 sanitizer 编译——即尽力而为绝不阻断构建。这一逻辑实现在 sanitize-helpers.cmake 中探测不到可用标志时把对应编译器的 flags 缓存为空字符串并给出警告。3.3 混合编译器目标会自动跳过不同编译器对 sanitizer 的实现不同。如果某个目标同时混用 C 与 Fortran 源码却分别使用 clang 与 gfortran 编译就会在链接期出现 sanitizer 运行时库冲突。模块通过sanitizer_target_compilers()sanitize-helpers.cmake逐个解析目标源文件的扩展名、映射到 CMake 语言、收集实际使用的编译器 ID 集合一旦发现一个目标由多种不兼容编译器编译见 FindSanitizers.cmake会打印警告并对该目标禁用 sanitizer。3.4 静态链接开关SANITIZE_LINK_STATIC对 gcc 构建的目标如果出现 ASan 预加载或动态链接方面的问题例如运行时找不到 libasan可以开启静态链接cmake -DSANITIZE_ADDRESSOn -DSANITIZE_LINK_STATICOn ..该选项定义于 FindSanitizers.cmake。当启用且编译器为 GNU 时sanitize-helpers.cmake 会额外探测-static-libasan、-static-libtsan等-static-libsanitizer标志并合并进编译参数PREFIX会被转为小写例如 ASan →-static-libasan。四、为目标启用 sanitizer4.1 add_sanitizers()最核心的入口函数定义目标之后调用add_sanitizers(TARGET...)即可一次性为若干目标启用全部已开启的 sanitizerfind_package(Sanitizers) add_executable(some_exe foo.c bar.c) add_sanitizers(some_exe) add_library(some_lib foo.c bar.c) add_sanitizers(some_lib)函数内部逻辑见 FindSanitizers.cmake若四个开关全部为Off立即返回不产生任何副作用对每个目标先检查类型INTERFACE_LIBRARY无法被直接编译打印警告后跳过检查该目标是否由多种不兼容编译器编译是则跳过并警告分别调用add_sanitize_address()/add_sanitize_thread()/add_sanitize_memory()/add_sanitize_undefined()每个子函数内部会再次判断对应开关是否打开并把探测好的 flags 注入目标的编译与链接参数target_compile_options(... PUBLIC ...)与target_link_options(... PUBLIC ...)见 sanitize-helpers.cmake。因此只有被add_sanitizers()显式指定的目标才会带 sanitizer 编译其它目标不受影响——这保证了只 sanitize 想 sanitize 的目标。4.2 sanitizer_add_blacklist_file()黑名单文件某些第三方源码或特定文件不宜做 sanitize例如已知会产生误报的代码可以用黑名单排除sanitizer_add_blacklist_file(blacklist.txt)该函数见 FindSanitizers.cmake会把相对路径解析为CMAKE_CURRENT_SOURCE_DIR下的绝对路径再探测编译器是否支持-fsanitize-blacklistFILE标志支持则把该标志同样加入目标的编译参数。4.3 自带测试验证模块自身的冒烟用例模块自带一组冒烟测试tests/CMakeLists.txt其流程本身就是一个绝佳的用法示例set(SANITIZE_ADDRESS TRUE) find_package(Sanitizers) add_sanitized_testcase(asan_test_cpp asan_test.cpp) add_sanitized_testcase(shortest_ext_test_cpp shortest.ext.test.cpp) set_tests_properties(asan_test_cpp shortest_ext_test_cpp PROPERTIES WILL_FAIL TRUE)其中add_sanitized_testcase()先构造可执行目标再调用add_sanitizers()最后通过WILL_FAIL TRUE声明这些测试用例故意写出内存错误期望被 ASan 捕获后失败退出——这正是验证sanitizer 确实在工作的标准手法。shortest.ext.test.cpp则顺带覆盖了sanitizer_lang_of_source()对带多个点号的源文件扩展名解析逻辑。五、运行被 sanitize 的程序5.1 常规运行sanitizer 是在程序运行期进行检测的。构建完成后直接运行目标即可例如./some_exe一旦触发错误ASan/UBSan 等会在终端打印详细的错误报告出错源码位置、调用栈、问题类型并让进程以非零状态退出。5.2 asan-wrapperLD_PRELOAD 预加载某些场景下例如你本来就要LD_PRELOAD另一个库到目标程序里ASan 库需要被最先预加载才能正常工作。此时应使用模块提供的包装脚本 asan-wrapper通过ASan_WRAPPER变量获取其路径${ASan_WRAPPER} myexe arg1 ...脚本行为见 asan-wrapper非 Linux 平台直接透传执行exec $因为 macOS 等平台通常不受影响Linux 下先用ldd $1从目标程序依赖中提取出 libasan 的实际路径找到后把它前置到LD_PRELOAD已有值时拼接为$libasan:$LD_PRELOAD保证 libasan 最先加载最后exec $原样执行程序与参数。该脚本会在启用SANITIZE_ADDRESS时由 FindASan.cmake 通过find_program(ASan_WRAPPER asan-wrapper PATHS ${CMAKE_MODULE_PATH})自动定位。六、在 Fluent Bit / ChunkIO 中的实际打开方式结合前文 ChunkIO 的集成代码要在本仓库构建时开启 AddressSanitizer可以在 ChunkIO 根目录执行cmake -DCIO_SANITIZE_ADDRESSOn -DCIO_TESTSOn ..构建过程中会看到-- Enabling address sanitizer的提示随后 ChunkIO 的库与测试目标都会被注入-g -fsanitizeaddress -fno-omit-frame-pointer等参数。测试目标经add_sanitizers()挂载后运行ctest即可在内存错误发生时获得 ASan 报告。这同样适用于 Fluent Bit 主仓库的调试可在其顶层 CMake 配置中按需传入-DSANITIZE_ADDRESSOn并保证CMAKE_MODULE_PATH指向 lib/chunkio/cmake/sanitizers-cmake/cmake 目录。七、常见问题速查问题现象原因与处理配置时出现 not available for XXX compiler 警告编译器不支持该 sanitizer构建继续目标不带 sanitizer目标被警告跳过目标是INTERFACE_LIBRARY或由多种不兼容编译器编译如 clang gfortran 混用 C/FortranASan 运行时报预加载/动态链接错误加-DSANITIZE_LINK_STATICOn让 gcc 静态链接 libasanTSan/MSan 被自动关闭仅支持 64 位TSan 限 Linux/macOSMSan 限 Linux同时开启 ASan 与 TSan/MSan、或 TSan 与 MSan直接FATAL_ERROR二者互不兼容需要排除部分源码用sanitizer_add_blacklist_file(blacklist.txt)注入-fsanitize-blacklist需预加载场景用${ASan_WRAPPER} myexe arg1 ...运行结语sanitizers-cmake 的价值在于把探测编译器能力、挑选正确标志、注入编译与链接参数、处理平台与编译器组合限制这套繁琐且易错的流程封装成四个开关与两个函数让开发者把精力集中在修复问题而不是配置工具链上。本文所述的一切行为均可在仓库源码中逐行验证入口在 FindSanitizers.cmake探测与注入逻辑在 sanitize-helpers.cmake各 sanitizer 的开关与平台约束分别在 FindASan.cmake、FindTSan.cmake、FindMSan.cmake、FindUBSan.cmake实战集成参考 lib/chunkio/CMakeLists.txt。【免费下载链接】fluent-bitFast and Lightweight Logs, Metrics and Traces processor for Linux, BSD, OSX and Windows项目地址: https://gitcode.com/GitHub_Trending/fl/fluent-bit创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
延伸阅读

更多相关文章

2026/11/6 21:25:58

多模型路由不生效?TaoToken 这样改 OpenCode 的 provider

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/11/4 21:53:12

shadPS4 手动更新游戏版本指南:Bloodborne 1.00 → 1.09 实操

shadPS4 手动更新游戏版本指南:Bloodborne 1.00 → 1.09 实操 【免费下载链接】shadPS4 PlayStation 4 emulator for Windows, Linux, macOS and FreeBSD written in C 项目地址: https://gitcode.com/GitHub_Trending/sh/shadPS4 从 PS4 上提出来 1.00 的基…

2026/11/11 20:27:03

平湖电工证考试报名良心建议:证书过期了不知道怎么复审延期

平湖电工证考试报名良心建议:证书过期了不知道怎么复审延期 证书过期了不知道怎么复审延期,这事儿真让人头疼。尤其是像平湖电工证考试报名这种必须按时办理的业务,一旦错过,轻则影响工作,重则面临违规处罚。作为在应急管理领域干了十多年的老手,我来给…

2026/11/11 20:27:03

职高可以什么电工证?2026河南最新政策下,电工证该怎么选

职高可以什么电工证?2026河南最新政策下,电工证该怎么选 你是不是正愁找不到工作,因为缺一张特种作业证?2026年河南最新政策下,职高毕业生考电工证已经不是难事,但你得搞清楚到底能考什么证、怎么考、能不能用。这篇文章就带你一步步了解清楚。…

2026/11/11 20:27:03

东莞在哪考电工证好 电工证含金量到底怎么算

东莞在哪考电工证好 电工证含金量到底怎么算 你是不是正被“急需特种作业证才能上岗找工作”这句话逼得喘不过气?东莞哪家机构考电工证靠谱?有没有含金量高的电工证?这些问题,我作为干了10年特种作业证培训和报考指导的“老江湖”,今天给你讲透彻。…

2026/11/11 20:27:03

考电工证难度有多大啊 2026河南最新政策下怎么避免交了钱还白忙

考电工证难度有多大啊 2026河南最新政策下怎么避免交了钱还白忙 怕考不过白交培训费,这几乎是每个想考电工证的河南人心里的共同恐惧。尤其是在2026年河南最新政策出台后,很多报考者开始担心:考电工证难度有多大啊?培训费是不是白交?今天我们就…

2026/11/11 20:27:03

异地如何考电工证?郑州报考避坑指南帮你搞定学历门槛

异地如何考电工证?郑州报考避坑指南帮你搞定学历门槛 你是不是也担心自己学历不高,连电工证都报不上?别急,这事儿咱们得说清楚。在郑州甚至全国,很多持证人都没有高学历背景,照样考了电工证,找上了稳定工作。只要你符合基本条件, 异地如何考电工证…

2026/11/11 20:11:14

嘉定电工证在哪里学?考前押题助你一次过!

嘉定电工证在哪里学?考前押题助你一次过! 怕考不过白交培训费?别急,教你如何在嘉定地区顺利报考电工证,还有考前押题攻略,确保你一次拿证不走弯路! 为什么嘉定电工证报考要谨慎选择机构?…

2026/11/11 12:42:59

电工证丢失还能补吗?千万别踩坑,丢了证等于失业

电工证丢失还能补吗?千万别踩坑,丢了证等于失业 你正在找工作,但手里的电工证突然丢了,这下怎么办?别急,先别慌, 电工证丢失还能补吗 ?答案是肯定的,但 千万别踩坑 ,补办流程如果不了解,可能会耽误你上岗、甚至影响到你的收入。…

2026/11/11 0:02:26

考低压电工证通过率考试真题与备考技巧

低压电工证通过率高不高?学历不高也能考,值不值得考? 你是不是总听说电工证能帮你找高薪工作,但又担心自己学历不够,考不上?其实,低压电工证考试门槛并没有你想象中那么高,关键是方法对不对。这篇文章就告诉你, 考低压电工证通过率到底有多高 ,…

2026/11/11 0:02:26

低压电工证学时千万别踩坑,濮阳毕业生怎么避坑报名

低压电工证学时千万别踩坑,濮阳毕业生怎么避坑报名 你是不是也和我一样,刚毕业就听说低压电工证学时必须达标才能上岗?可一打听,发现报名机构五花八门,价格参差不齐, 不知道去哪报名怕被中介坑…

2026/11/11 20:27:01

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代,基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而,与配合度高的人类不同,宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态,更无法控制光照环境。实际应用中,我们常…

2026/11/10 10:29:37

SSM电子书店源码全解析:结构、原理、部署与排错实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑