Guide for Memory Sanitizer usage

I was trying to use msan for one of my projects, which worked great for like 10 minutes, until I hit something that used a std::string. Then I found out that MemorySanitizer requires that all program code is instrumented. This also includes any libraries that the program depends on, even libc.

So then I found this that describes how to do what I want, mostly, except it’s for an old enough version of LLVM that it doesn’t work anymore. The links from Also see are also either old, or not helpful.

I managed to build something by changing the command to -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi;libunwind;libc". After more fiddling to make my project work, the best I managed to do is to get to errors like this:

.../llvm-project/build/include/c++/v1/__thread/support/pthread.h:198:43: error: use of undeclared identifier 'errno'

It seems it can’t find anything that’s from the C library, like errno, memchr, memcpy, FP_*, etc.

Even finding the libc++ docs was me finding the docs for 3.8 and then just trying out versions until I hit 404. I think those are the latest docs, but I don’t see an year mentioned anywhere.

I feel like this is pretty arcane knowledge compared to how easy is to run the other sanitizers. Is there an uptodate guide, dockerfile, or anything else that could help me?

1 Like

Maybe the script we use for the MSAN buildbot could be helpful? llvm-zorg/zorg/buildbot/builders/sanitizers/buildbot_functions.sh at main · llvm/llvm-zorg · GitHub

1 Like

I tried to make it work, but I got back to similar errors:

#12 [8/8] RUN clang++-20 -fsanitize=memory -stdlib=libc++ -Lllvm/build/lib -lc++abi -Illvm/build/include -Illvm/build/include/c++/v1 main.cpp && ./a.out
#12 0.232 In file included from main.cpp:2:
#12 0.232 In file included from llvm/build/include/c++/v1/string:594:
#12 0.232 In file included from llvm/build/include/c++/v1/__algorithm/remove.h:12:
#12 0.232 In file included from llvm/build/include/c++/v1/__algorithm/find.h:32:
#12 0.232 llvm/build/include/c++/v1/cwchar:136:9: error: target of using declaration conflicts with declaration already in scope
#12 0.232   136 | using ::wint_t _LIBCPP_USING_IF_EXISTS;
#12 0.232       |         ^
#12 0.233 /usr/include/x86_64-linux-gnu/bits/types/wint_t.h:20:23: note: target of using declaration
#12 0.233    20 | typedef __WINT_TYPE__ wint_t;
#12 0.233       |                       ^
#12 0.233 llvm/build/include/c++/v1/cwctype:75:1: note: conflicting declaration
#12 0.233    75 | using ::wint_t _LIBCPP_USING_IF_EXISTS;
#12 0.233       | ^
#12 0.242 In file included from main.cpp:2:
#12 0.242 In file included from llvm/build/include/c++/v1/string:600:
#12 0.242 llvm/build/include/c++/v1/__functional/hash.h:39:8: error: reference to unresolved using declaration
#12 0.242    39 |   std::memcpy(std::addressof(__r), __p, sizeof(__r));
#12 0.242       |        ^
#12 0.242 llvm/build/include/c++/v1/cstring:82:1: note: using declaration annotated with 'using_if_exists' here
#12 0.242    82 | using ::memcpy _LIBCPP_USING_IF_EXISTS;
#12 0.242       | ^
#12 0.299 In file included from main.cpp:2:
#12 0.299 In file included from llvm/build/include/c++/v1/string:618:
#12 0.299 In file included from llvm/build/include/c++/v1/__memory_resource/polymorphic_allocator.h:22:
#12 0.299 In file included from llvm/build/include/c++/v1/tuple:277:
#12 0.299 In file included from llvm/build/include/c++/v1/compare:171:
#12 0.299 In file included from llvm/build/include/c++/v1/cmath:331:
#12 0.299 llvm/build/include/c++/v1/math.h:395:31: error: use of undeclared identifier 'FP_NAN'
#12 0.299   395 |   return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL, FP_ZERO, __x);
#12 0.299       |                               ^
#12 0.299 llvm/build/include/c++/v1/math.h:395:39: error: use of undeclared identifier 'FP_INFINITE'
#12 0.299   395 |   return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL, FP_ZERO, __x);
#12 0.299       |                                       ^
#12 0.299 llvm/build/include/c++/v1/math.h:395:52: error: use of undeclared identifier 'FP_NORMAL'
#12 0.299   395 |   return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL, FP_ZERO, __x);
#12 0.299       |                                                    ^
#12 0.299 llvm/build/include/c++/v1/math.h:395:63: error: use of undeclared identifier 'FP_SUBNORMAL'
#12 0.299   395 |   return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL, FP_ZERO, __x);
#12 0.300       |                                                               ^
#12 0.300 llvm/build/include/c++/v1/math.h:395:77: error: use of undeclared identifier 'FP_ZERO'
#12 0.300   395 |   return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL, FP_ZERO, __x);
#12 0.300       |                                                                             ^
#12 0.303 llvm/build/include/c++/v1/math.h:400:31: error: use of undeclared identifier 'FP_NAN'
#12 0.303   400 |   return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL, FP_ZERO, __x);
#12 0.303       |                               ^
#12 0.303 llvm/build/include/c++/v1/math.h:400:39: error: use of undeclared identifier 'FP_INFINITE'
#12 0.303   400 |   return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL, FP_ZERO, __x);
#12 0.303       |                                       ^
#12 0.303 llvm/build/include/c++/v1/math.h:400:52: error: use of undeclared identifier 'FP_NORMAL'
#12 0.303   400 |   return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL, FP_ZERO, __x);
#12 0.303       |                                                    ^
#12 0.303 llvm/build/include/c++/v1/math.h:400:63: error: use of undeclared identifier 'FP_SUBNORMAL'
#12 0.303   400 |   return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL, FP_ZERO, __x);
#12 0.303       |                                                               ^
#12 0.303 llvm/build/include/c++/v1/math.h:400:77: error: use of undeclared identifier 'FP_ZERO'
#12 0.303   400 |   return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL, FP_ZERO, __x);
#12 0.303       |                                                                             ^
#12 0.306 llvm/build/include/c++/v1/math.h:405:31: error: use of undeclared identifier 'FP_NAN'
#12 0.306   405 |   return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL, FP_ZERO, __x);
#12 0.306       |                               ^
#12 0.306 llvm/build/include/c++/v1/math.h:405:39: error: use of undeclared identifier 'FP_INFINITE'
#12 0.306   405 |   return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL, FP_ZERO, __x);
#12 0.306       |                                       ^
#12 0.306 llvm/build/include/c++/v1/math.h:405:52: error: use of undeclared identifier 'FP_NORMAL'
#12 0.306   405 |   return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL, FP_ZERO, __x);
#12 0.306       |                                                    ^
#12 0.306 llvm/build/include/c++/v1/math.h:405:63: error: use of undeclared identifier 'FP_SUBNORMAL'
#12 0.306   405 |   return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL, FP_ZERO, __x);
#12 0.306       |                                                               ^
#12 0.306 llvm/build/include/c++/v1/math.h:405:77: error: use of undeclared identifier 'FP_ZERO'
#12 0.306   405 |   return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL, FP_ZERO, __x);
#12 0.306       |                                                                             ^
#12 0.307 llvm/build/include/c++/v1/math.h:410:21: error: use of undeclared identifier 'FP_ZERO'
#12 0.307   410 |   return __x == 0 ? FP_ZERO : FP_NORMAL;
#12 0.307       |                     ^
#12 0.307 llvm/build/include/c++/v1/math.h:410:31: error: use of undeclared identifier 'FP_NORMAL'
#12 0.307   410 |   return __x == 0 ? FP_ZERO : FP_NORMAL;
#12 0.307       |                               ^
#12 0.336 fatal error: too many errors emitted, stopping now [-ferror-limit=]
#12 0.485 20 errors generated.
#12 ERROR: process "/bin/sh -c $CXX -fsanitize=memory -stdlib=libc++ -Lllvm/build/lib -lc++abi -Illvm/build/include -Illvm/build/include/c++/v1 main.cpp && ./a.out" did not complete successfully: exit code: 1
------
 > [8/8] RUN clang++-20 -fsanitize=memory -stdlib=libc++ -Lllvm/build/lib -lc++abi -Illvm/build/include -Illvm/build/include/c++/v1 main.cpp && ./a.out:
0.306   405 |   return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL, FP_ZERO, __x);
0.306       |                                                                             ^
0.307 llvm/build/include/c++/v1/math.h:410:21: error: use of undeclared identifier 'FP_ZERO'
0.307   410 |   return __x == 0 ? FP_ZERO : FP_NORMAL;
0.307       |                     ^
0.307 llvm/build/include/c++/v1/math.h:410:31: error: use of undeclared identifier 'FP_NORMAL'
0.307   410 |   return __x == 0 ? FP_ZERO : FP_NORMAL;
0.307       |                               ^
0.336 fatal error: too many errors emitted, stopping now [-ferror-limit=]
0.485 20 errors generated.

This are the errors from building the dockerfile from here.

Edit: Happy cake day!

If I do this change (add -nostdinc+, use -isystem and use LD_LIBRARY_PATH), it works for me

-RUN $CXX -fsanitize=memory -stdlib=libc++ -Lllvm/build/lib -lc++abi -Illvm/build/include -Illvm/build/include/c++/v1 main.cpp && ./a.out
+RUN $CXX -fsanitize=memory -stdlib=libc++ -nostdinc++ -Lllvm/build/lib -lc++abi -isystem llvm/build/include -isystem llvm/build/include/c++/v1 main.cpp && LD_LIBRARY_PATH=llvm/build/lib  ./a.out
1 Like

It works!!

Thank you very much, that was extremely helpful!
:cat_face: :partying_face:

Here’s a guide for doing this on Linux: link.

2 Likes