I wish to use the -fsanitize=memory
flag in clang to analyse a program like the following:
#include <string> #include <iostream> #include <fstream> using namespace std; void writeToFile(){ ofstream o; o.open("dum"); o<<"test"<<endl; //The error is here. //It does not matter if the file is opened this way, //or with o("dum"); o.close(); } int main(){ writeToFile(); }
As far as I know, this program is correct, but when I use clang++ san.cpp -fsanitize=memory
It fails (at runtime) with:
UMR in __interceptor_write at offset 0 inside [0x64800000e000, +5) ==9685== WARNING: MemorySanitizer: use-of-uninitialized-value #0 0x7f48d0899ae5 (/usr/lib/x86_64-linux-gnu/libstdc++.so.6+0x7bae5) #1 0x7f48d08d1787 (/usr/lib/x86_64-linux-gnu/libstdc++.so.6+0xb3787) #2 0x7f48d08d21e2 (/usr/lib/x86_64-linux-gnu/libstdc++.so.6+0xb41e2) #3 0x7f48d08cfd1e (/usr/lib/x86_64-linux-gnu/libstdc++.so.6+0xb1d1e) #4 0x7f48d08b1f2d (/usr/lib/x86_64-linux-gnu/libstdc++.so.6+0x93f2d) #5 0x7f48d16d60f5 in writeToFile() /home/daniel/programming/test/santest.cpp:10 #6 0x7f48d16d61f4 in main /home/daniel/programming/test/santest.cpp:15 #7 0x7f48d0261de4 (/lib/x86_64-linux-gnu/libc.so.6+0x21de4) #8 0x7f48d16d5e42 in _start (/home/daniel/programming/test/a.out+0x61e42) SUMMARY: MemorySanitizer: use-of-uninitialized-value ??:0 ??
How can I make this work properly?
Clang version 3.5, stdlibc++ version 6
Memory Sanitizer (MSan) is a fast detector used for uninitialized memory in C/C++ programs. It uses a compile-time instrumentation to ensure that all memory access at runtime uses only memory that has been initialized.
AddressSanitizer (or ASan) is an open source programming tool that detects memory corruption bugs such as buffer overflows or accesses to a dangling pointer (use-after-free). AddressSanitizer is based on compiler instrumentation and directly mapped shadow memory.
Because Valgrind does not require recompiling the program, it cannot detect some invalid memory accesses. One such bug is accessing memory out of the range of automatic (local) variables and global variables. (See the AddressSanitizer Stack Out of Bounds documentation.)
Address Sanitizer is a tool developed by Google detect memory access error such as use-after-free and memory leaks. It is built into GCC versions >= 4.8 and can be used on both C and C++ codes.
AddressSanitizer can optionally detect stack use after return problems. This is available by default, or explicitly ( -fsanitize-address-use-after-return=runtime ). To disable this check at runtime, set the environment variable ASAN_OPTIONS=detect_stack_use_after_return=0 .
The code is fine, of course but many similar errors are cause by the following requirement of clang's memory sanitizer tool:
MemorySanitizer (without a dynamic component) requires that the entire program code including libraries, (except libc/libm/libpthread, to some extent), is instrumented.
from here
The cplusplus runtime you are using libstdc++ is unistrumented and causes errors. You will unfortunately have to follow a somewhat fiddly process as described at that link to rebuild an instrumented libstdc++ or switch to libc++ (easier-ish)
There easiest way at this time is to build libc++ with memorysanitizer, then link your program against it.
This is how I did it some time ago, failing to handle libc++ build system: https://code.google.com/p/memory-sanitizer/source/browse/bootstrap/build_libcxx.sh
I heard there've been improvements on the libc++ side, maybe it would be possible to build it as usual (with something like CC=/path/to/clang CFLAGS=-fsanitize=memory).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With