为何Clang MemorySanitizer调用fstream open时产生未初始化值错误?
解决MemorySanitizer检测到std::ifstream::open中的未初始化值使用问题
我正尝试在项目中集成MemorySanitizer,以下代码触发了use-of-uninitialized-value错误:
#include <fstream> int main () { std::ifstream ifs; ifs.open ("test.txt", std::ifstream::in); char c = ifs.get(); // 此行不影响结果 if (!ifs.good()) { return -1; } ifs.close(); return 0; }
编译及运行命令与报错信息
$ clang -fsanitize=memory -fPIE -pie -fno-omit-frame-pointer -g -O3 main.cpp -lstdc++ $ ./a.out ==43028==WARNING: MemorySanitizer: use-of-uninitialized-value #0 0x55986e5d76ae in std::basic_ifstream<char, std::char_traits<char> >::open(char const*, std::_Ios_Openmode) /usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/fstream #1 0x55986e5d76ae in main /home/promanjuk/learn/sanityzers/main.cpp:5:7 #2 0x7f6389ffdd8f in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16 #3 0x7f6389ffde3f in __libc_start_main csu/../csu/libc-start.c:392:3 #4 0x55986e551334 in _start (/home/promanjuk/learn/sanityzers/a.out+0x21334) (BuildId: 597886c0634c006622192d0fa4c5ab7f169b7625) SUMMARY: MemorySanitizer: use-of-uninitialized-value /usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/fstream in std::basic_ifstream<char, std::char_traits<char> >::open(char const*, std::_Ios_Openmode) Exiting $ clang --version Ubuntu clang version 14.0.0-1ubuntu1 Target: x86_64-pc-linux-gnu Thread model: posix InstalledDir: /usr/bin
测试情况
在GodBolt上测试Clang 5.0至15.0版本均出现该错误,更早版本会产生链接错误。我尝试过保留/移除char c = ifs.get();语句,也测试了不同版本的Clang,但问题仍存在。
解决方法
这个错误属于MemorySanitizer与libstdc++之间的兼容性问题,并非代码逻辑错误,可通过以下方式解决:
- 改用libc++库编译:libc++对MemorySanitizer的支持更为完善,替换编译命令中的标准库即可:
clang -fsanitize=memory -fPIE -pie -fno-omit-frame-pointer -g -O3 main.cpp -stdlib=libc++ - 若必须使用libstdc++:
- 安装对应版本的libstdc++源码包(例如Ubuntu上的
libstdc++-11-dev) - 利用MemorySanitizer提供的工具生成libstdc++的初始化文件,消除误报(该步骤较为繁琐,参考官方文档操作)
- 临时方案:添加
-msan-keep-going参数让程序忽略错误继续运行,但这会屏蔽所有未初始化值的检测,不推荐用于正式项目。
- 安装对应版本的libstdc++源码包(例如Ubuntu上的
内容的提问来源于stack exchange,提问作者Павел Романюк
相关产品推荐
相关产品推荐

