如何在CI的CTest单元测试任务中采集带符号的core dumps
CTest CI环境采集自包含符号core dump的最简方案
优先推荐无需修改系统内核配置的CTest钩子方案,完全适配现有CTest流程:
方案1:CTest失败钩子+符号合并(无系统权限要求)
- 首先在项目根目录的
CMakeLists.txt中添加CTest失败回调配置:
if (BUILD_TESTING) set(CTEST_TEST_FAILURE_HOOK "${CMAKE_CURRENT_SOURCE_DIR}/capture_coredump.sh" CACHE FILEPATH "Test failure coredump capture hook") endif()
- 编写
capture_coredump.sh脚本,CTest会自动传入失败测试的可执行路径、进程ID等参数,脚本核心逻辑如下:
#!/bin/bash TEST_EXEC=$1 TEST_PID=$2 TEST_NAME=$(basename "$TEST_EXEC") DUMP_PATH="./artifacts/coredump_${TEST_NAME}_$(date +%s).dump" # 生成基础core文件 gdb --batch -ex "generate-core-file /tmp/core.tmp" "$TEST_EXEC" "$TEST_PID" > /dev/null 2>&1 # 合并符号到core文件,生成自包含的转储文件 eu-unstrip /tmp/core.tmp "$TEST_EXEC" -o "$DUMP_PATH" # 清理临时文件 rm -f /tmp/core.tmp
- 最终输出到artifacts目录的dump文件自带完整符号,无需额外匹配对应可执行文件,直接用gdb打开即可分析。
方案2:内核core_pattern自定义收集脚本(需root权限)
如果你有权限修改CI节点的内核参数,可以用全局采集方案:
- 调整core_pattern指向自定义收集脚本:
sysctl -w kernel.core_pattern="|/opt/coredump_collector.sh %e %p"
- 编写
/opt/coredump_collector.sh脚本,核心逻辑是从/proc/$PID/exe读取崩溃进程对应的带符号可执行文件,同样用eu-unstrip合并符号后写入artifacts目录即可。
依赖要求
两种方案都需要在CI镜像中提前预装工具:
- gdb(用于生成core文件)
- elfutils(提供
eu-unstrip工具实现符号合并) - 容器化CI需要给测试容器添加
SYS_PTRACE权限,否则ptrace相关操作会被限制。
内容的提问来源于stack exchange,提问作者Igor Pugachev
相关产品推荐
相关产品推荐

