基于CMake项目:用Clang动态分析时屏蔽外部库(如DBus)报告
我之前也碰到过一模一样的需求——用Clang的AddressSanitizer排查本地代码的内存问题,但被第三方库尤其是DBus的报错搞得头大。结合你给出的环境(CMake 3.9.5、Debian 4.14、Clang 4.0.1),给你分享几个亲测有效的解决方案:
1. 用ASAN黑名单精准屏蔽DBus错误
ASAN支持通过黑名单文件指定要忽略的库、函数或源文件,这是最直接的方法。
首先,在项目根目录创建一个asan_ignorelist.txt文件,写入针对DBus的规则:
# 屏蔽整个DBus系统库的所有报错 libdbus-1.so.3:* # 或者屏蔽所有以dbus_开头的函数(更精准) fun:dbus_* # 如果知道DBus源码路径,也可以屏蔽对应源文件的报错 src:/usr/src/dbus-*
然后在CMakeLists.txt里配置编译器和链接器参数,引入这个黑名单:
# 给C/C++代码添加ASAN和黑名单参数 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address -fsanitize-blacklist=${CMAKE_SOURCE_DIR}/asan_ignorelist.txt") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -fsanitize-blacklist=${CMAKE_SOURCE_DIR}/asan_ignorelist.txt") # 链接时也要带上ASAN参数 set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=address")
注意:Clang 4.0.1用的是
-fsanitize-blacklist参数,后续版本才改名为-fsanitize-ignorelist,别搞错了。
2. 只给本地代码启用ASAN
另一种思路是不对第三方库启用ASAN,只给自己的代码加检测。这样第三方库的内存操作就不会被ASAN追踪,自然不会弹出报错。
在CMake里,不要全局设置ASAN参数,而是针对你的本地目标单独配置:
# 假设你的本地代码编译成名为my_app的可执行文件 add_executable(my_app src/main.c src/utils.c src/module.c) # 仅给这个目标添加ASAN编译参数(PRIVATE确保不会传递给依赖) target_compile_options(my_app PRIVATE -fsanitize=address) # 因为你的CMake版本是3.9.5,还没有target_link_options,用set_target_properties替代 set_target_properties(my_app PROPERTIES LINK_FLAGS "-fsanitize=address")
这样一来,通过find_package或add_subdirectory引入的第三方库(包括DBus)不会带上ASAN参数,也就不会触发ASAN的错误检测了。
3. 运行时过滤ASAN输出(应急方案)
如果上面的方法暂时没生效,还可以在运行程序时直接过滤掉DBus相关的报错信息:
./my_app 2>&1 | grep -v "dbus-"
这个方法简单粗暴,适合快速排查,但不如前两种方法精准,可能会漏掉一些和DBus相关的本地代码错误。
内容的提问来源于stack exchange,提问作者Alvaro Denis Acosta
相关产品推荐
相关产品推荐

