启用Sanitizer时空main函数偶发段错误,求排查思路
排查Sanitizer启用时偶发段错误/死循环问题的思路
问题背景
- 测试环境:Ubuntu 22.04 + g++-11.4,最小测试代码仅为
int main( int argc, char** argv ) { return 0; } - 核心现象:启用Sanitizer(Address/Leak/Undefined组合或单独Leak)时,程序偶发段错误或无限循环输出
AddressSanitizer:DEADLYSIGNAL;禁用Sanitizer则完全正常 - 跨环境验证:Ubuntu 24.04无此问题,Ubuntu 18.04下单独启用Address Sanitizer也偶发相同故障,且多台Ubuntu 22.04机器均能复现
具体排查步骤
1. 升级Sanitizer依赖库
Ubuntu 22.04默认的libasan/liblsan版本可能存在已知bug,执行命令更新相关库:
sudo apt update && sudo apt install --only-upgrade libasan6 liblsan0
(g++-11对应libasan6,可通过dpkg -l | grep libasan确认版本匹配)
2. 启用core dump分析崩溃现场
打开core dump功能捕获崩溃细节:
ulimit -c unlimited
运行程序直到崩溃,生成core文件后用gdb分析:
gdb ./a.out core
在gdb中执行bt full查看完整调用栈,确认崩溃发生在用户代码还是Sanitizer运行时库中。
3. 调整Sanitizer运行时参数
添加调试参数获取更详细的错误日志:
- 单独启用Leak Sanitizer时:
LSAN_OPTIONS=verbosity=2:log_threads=1 ./a.out - 启用Address Sanitizer时:
ASAN_OPTIONS=detect_leaks=0:verbosity=2:log_path=asan.log ./a.out,将日志输出到文件避免终端刷屏 - 尝试切换 unwind 模式:
ASAN_OPTIONS=fast_unwind_on_malloc=0 ./a.out,慢速unwind可能提供更准确的栈信息
4. 测试不同g++版本
在Ubuntu 22.04下尝试安装更高版本的g++,验证是否为旧版本编译器的bug:
sudo apt install g++-12 g++-12 -std=gnu++14 -fsanitize=leak main.cpp ./a.out
5. 验证内核兼容性
Sanitizer运行时依赖内核特性,检查Ubuntu 22.04与24.04的内核版本差异:
uname -r
尝试升级Ubuntu 22.04的内核到最新稳定版:
sudo apt install linux-generic-hwe-22.04
6. 排查系统资源问题
偶发故障可能与资源不足有关,运行程序时监控内存、CPU使用率:
top -p $(pgrep a.out)
同时检查OOM Killer日志:
dmesg | grep -i oom
若Sanitizer运行时占用内存过高被OOM Killer终止,也会出现类似段错误的现象。
内容的提问来源于stack exchange,提问作者Finkman
相关产品推荐
相关产品推荐

