c++ - Instrumentation:融合 gcov / ASan 还是拆分成独立的构建(+ 后续测试)?
问题描述
在我的(基于 linux 的)CI/CD 管道中,我目前正在做(基本上):
- 构建发布(cmake out-of-source-build)
- 测试/(自定义)模糊构建
- 构建以仪器为中心的 = gcov + ASan(再次:cmake)
- 测试/(自定义)模糊构建
- 进程覆盖率 (gcovr)
这现在基于 GCC 10。
在考虑添加基于 Sonarqube 的分析时(这意味着使用构建包装器,希望它与描述的一样非侵入性 -> 由于有些害怕,我什至考虑了第三次构建!),我想知道我采取的原始方法:
将代码覆盖和内存清理工具融合到一个构建中是否安全/正确/一个好主意?
与独立构建相比,我是否有可能失去某些东西(例如 ASan 推理的能力、覆盖计数准确性、非线性减速)(遗憾的是,这增加了我们需要运行两次测试所需的时间)?
编辑:
对于它的价值,关于使用 gcov/asan对我来说意味着什么的更多细节(是的:它不像 cmake-def 的其他部分那样干净):
# Code Coverage Analysis
option(ENABLE_CODE_COVERAGE_ANALYSIS "Enable instrumentalization-based code-coverage" OFF)
if (${ENABLE_CODE_COVERAGE_ANALYSIS})
message(STATUS "Instrumentalize for code-coverage analysis.")
add_definitions(--coverage)
set(COV_LINKING gcov)
endif()
# ASAN Memory Sanitization
option(ENABLE_ASAN "Enable ASAN" OFF)
if (${ENABLE_ASAN})
message(STATUS "Instrumentalize for ASAN")
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")
# suppress GRPC ASAN stuff
# https://github.com/grpc/grpc/pull/22325/files
add_definitions("-DGRPC_ASAN_SUPPRESSED")
endif()
解决方案
如果您有测试验证非常短的时间,那么这些测试无论如何都应该使用 Release 类型的编译运行(没有调试,所以也没有消毒剂,并且完全优化)。
任何其他测试,那些验证与时间相反的正确性的测试,都应该在完全调试、清理、覆盖和不优化的情况下运行。这会增加您及早发现问题的机会。
就我而言,我在进行开发时有三种通用模式:
- 调试
- 消毒剂(带调试)
- 发布
在大多数情况下,我使用 Debug 运行,当似乎存在内存问题时,我使用 Sanitizer 版本进行测试。
但是,当准备好运行覆盖测试时,我会运行一个脚本,该脚本会打开调试、清理程序、覆盖并删除所有优化。当我运行这个脚本时,它做的第一件事就是删除 COVERAGE 文件夹并重建所有内容,例如,它可能是这样的(删除了错误检查):
SOURCE=`pwd`
rm -rf ../COVERAGE
cd ../COVERAGE
cmake $SOURCE
make -DCOVERAGE=ON -DSANITIZER=ON -DCMAKE_BUILD_TYPE=Debug ...
tests/unittests
lcov ...
genhtml ...
所以我现在已经运行了一段时间,但我没有需要计时的测试。话虽如此,使用该getrusage()
功能,我可以添加计时测试。在大多数情况下,这并不是真正让我觉得有用的东西。特别是因为时间非常依赖于外部事物,例如 CPU、网络、SSD 与 HDD 等。
我的旧电脑的主要问题是内存。使用消毒剂会使用更多的 RAM,因此如果您必须能够在较小的系统上运行测试(例如具有 4Gb RAM 的 VirtualBox 计算机),那么它可能变得不可行。在我的新电脑上,我有 512Gb 的 RAM,所以我没有这个问题。
推荐阅读
- django - Django REST Serializer 使用错误的模型进行序列化
- python - python文件写入程序运行时如何更新桌面上的文件大小
- javascript - 使用 d3.js 更新表数据
- c# - C#捕获从不在进程中的函数返回的异常?
- r - 如何设置仅在输入 3 时才显示集合向量的函数?
- javascript - 如果 URI 没有改变,例如在单页应用程序上,如何检测用户是否在新页面上?
- angular - Angular Kendo UI 全局访问
- php - 内连接循环通过
- git - 如何 git rebase 从另一个分支直接到 master 分支?
- javascript - 受控数字比例映射