title: Using Memory Sanitizer instrumented libc++
body: <p>I have built an instrumented libc++ as described <a href="https://github.com/google/sanitizers/wiki/MemorySanitizerLibcxxHowTo" rel="nofollow noreferrer">here</a>. I have set the flags as the above site suggests:</p>
  
  <pre><code>MSAN_CFLAGS="-fsanitize=memory -stdlib=libc++ -L/path_to/llvm-build-msan/lib -lc++abi -I/path_to/llvm-build-msan/include -I/path_to/llvm-build-msan/include/c++/v1"
  </code></pre>
  
  <p>and tried to build this:</p>
  
  <pre><code>#include &lt;string.h&gt;
  #include &lt;stdio.h&gt;
  
  int main(){
      char str[] = "This is a sample string";
      char * pch;
      printf ("Looking for the 's' character in \"%s\"...\n",str);
      pch=strchr(str,'s');
  }
  </code></pre>
  
  <p>with: <code>clang++ ${MSAN_CFLAGS} m.cpp</code>. I got:</p>
  
  <pre><code>In file included from m.cpp:1:
  /path_to/llvm-build-msan/include/c++/v1/string.h:74:64: error: use of undeclared identifier 'strchr'
  char* __libcpp_strchr(const char* __s, int __c) {return (char*)strchr(__s, __c);}
                                                                 ^
  /path_to/llvm-build-msan/include/c++/v1/string.h:81:75: error: use of undeclared identifier 'strpbrk'
  char* __libcpp_strpbrk(const char* __s1, const char* __s2) {return (char*)strpbrk(__s1, __s2);}
                                                                            ^
  /path_to/llvm-build-msan/include/c++/v1/string.h:88:65: error: use of undeclared identifier 'strrchr'; did you mean 'strchr'?
  char* __libcpp_strrchr(const char* __s, int __c) {return (char*)strrchr(__s, __c);}
                                                                  ^
  /path_to/llvm-build-msan/include/c++/v1/string.h:76:13: note: 'strchr' declared here
  const char* strchr(const char* __s, int __c) {return __libcpp_strchr(__s, __c);}
              ^
  /path_to/llvm-build-msan/include/c++/v1/string.h:95:49: error: unknown type name 'size_t'
  void* __libcpp_memchr(const void* __s, int __c, size_t __n) {return (void*)memchr(__s, __c, __n);}
                                                  ^
  /path_to/llvm-build-msan/include/c++/v1/string.h:97:46: error: unknown type name 'size_t'
  const void* memchr(const void* __s, int __c, size_t __n) {return __libcpp_memchr(__s, __c, __n);}
                                               ^
  /path_to/llvm-build-msan/include/c++/v1/string.h:99:46: error: unknown type name 'size_t'
        void* memchr(      void* __s, int __c, size_t __n) {return __libcpp_memchr(__s, __c, __n);}
                                               ^
  /path_to/llvm-build-msan/include/c++/v1/string.h:102:74: error: use of undeclared identifier 'strstr'; did you mean 'strchr'?
  char* __libcpp_strstr(const char* __s1, const char* __s2) {return (char*)strstr(__s1, __s2);}
                                                                           ^
  /path_to/llvm-build-msan/include/c++/v1/string.h:78:13: note: 'strchr' declared here
        char* strchr(      char* __s, int __c) {return __libcpp_strchr(__s, __c);}
              ^
  /path_to/llvm-build-msan/include/c++/v1/string.h:102:74: error: no matching function for call to 'strchr'
  char* __libcpp_strstr(const char* __s1, const char* __s2) {return (char*)strstr(__s1, __s2);}
                                                                           ^
  /path_to/llvm-build-msan/include/c++/v1/string.h:78:13: note: candidate disabled: &lt;no message provided&gt;
        char* strchr(      char* __s, int __c) {return __libcpp_strchr(__s, __c);}
              ^
  /path_to/llvm-build-msan/include/c++/v1/string.h:102:81: error: cannot initialize a parameter of type 'char *' with an lvalue of type 'const char *'
  char* __libcpp_strstr(const char* __s1, const char* __s2) {return (char*)strstr(__s1, __s2);}
                                                                                  ^~~~
  /path_to/llvm-build-msan/include/c++/v1/string.h:78:32: note: passing argument to parameter '__s' here
        char* strchr(      char* __s, int __c) {return __libcpp_strchr(__s, __c);}
                                 ^
  m.cpp:7:5: error: use of undeclared identifier 'printf'
      printf ("Looking for the 's' character in \"%s\"...\n",str);
      ^
  10 errors generated.
  </code></pre>
  
  <p>I also tried to build a memory sanitized <code>clang++</code> using the same method as to build <code>libc++</code>, but I got:</p>
  
  <pre><code>[  9%] Building Checkers.inc...
  ==20994==WARNING: MemorySanitizer: use-of-uninitialized-value
      #0 0x53bf93 in _M_lower_bound /usr/bin/../lib/gcc/x86_64-linux-gnu/7.2.0/../../../../include/c++/7.2.0/bits/stl_tree.h:1887:7
      #1 0x53bf93 in std::_Rb_tree&lt;std::__cxx11::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt;, std::pair&lt;std::__cxx11::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt; const, std::unique_ptr&lt;llvm::Record, std::default_delete&lt;llvm::Record&gt; &gt; &gt;, std::_Select1st&lt;std::pair&lt;std::__cxx11::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt; const, std::unique_ptr&lt;llvm::Record, std::default_delete&lt;llvm::Record&gt; &gt; &gt; &gt;, std::less&lt;std::__cxx11::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt; &gt;, std::allocator&lt;std::pair&lt;std::__cxx11::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt; const, std::unique_ptr&lt;llvm::Record, std::default_delete&lt;llvm::Record&gt; &gt; &gt; &gt; &gt;::find(std::__cxx11::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt; const&amp;) const /usr/bin/../lib/gcc/x86_64-linux-gnu/7.2.0/../../../../include/c++/7.2.0/bits/stl_tree.h:2536
      #2 0x6f0f32 in find /usr/bin/../lib/gcc/x86_64-linux-gnu/7.2.0/../../../../include/c++/7.2.0/bits/stl_map.h:1174:21
      #3 0x6f0f32 in getClass /path_to/llvm/include/llvm/TableGen/Record.h:1536
      #4 0x6f0f32 in llvm::TGParser::ParseClass() /path_to/llvm/lib/TableGen/TGParser.cpp:2130
      #5 0x6f0924 in llvm::TGParser::ParseObject(llvm::MultiClass*) /path_to/llvm/lib/TableGen/TGParser.cpp:2669:29
      #6 0x6fc77a in ParseObjectList /path_to/llvm/lib/TableGen/TGParser.cpp:2678:9
      #7 0x6fc77a in llvm::TGParser::ParseFile() /path_to/llvm/lib/TableGen/TGParser.cpp:2686
      #8 0x688049 in llvm::TableGenMain(char*, bool (*)(llvm::raw_ostream&amp;, llvm::RecordKeeper&amp;)) /path_to/llvm/lib/TableGen/Main.cpp:96:14
      #9 0x61b5d5 in main /path_to/llvm/tools/clang/utils/TableGen/TableGen.cpp:287:10
      #10 0x7f03af5691c0 in __libc_start_main /build/glibc-CxtIbX/glibc-2.26/csu/../csu/libc-start.c:308
      #11 0x424d99 in _start (/path_to/llvm-build/bin/clang-tblgen+0x424d99)
  
  SUMMARY: MemorySanitizer: use-of-uninitialized-value /usr/bin/../lib/gcc/x86_64-linux-gnu/7.2.0/../../../../include/c++/7.2.0/bits/stl_tree.h:1887:7 in _M_lower_bound
  Exiting
  tools/clang/include/clang/StaticAnalyzer/Checkers/CMakeFiles/ClangSACheckers.dir/build.make:94: recipe for target 'tools/clang/include/clang/StaticAnalyzer/Checkers/Checkers.inc.tmp' failed
  make[3]: *** [tools/clang/include/clang/StaticAnalyzer/Checkers/Checkers.inc.tmp] Error 77
  CMakeFiles/Makefile2:18275: recipe for target 'tools/clang/include/clang/StaticAnalyzer/Checkers/CMakeFiles/ClangSACheckers.dir/all' failed
  make[2]: *** [tools/clang/include/clang/StaticAnalyzer/Checkers/CMakeFiles/ClangSACheckers.dir/all] Error 2
  make[2]: *** Waiting for unfinished jobs....
  </code></pre>
  
  <p>Any suggestions how to compile the above code?</p>
  
  <p>Of course, <code>clang++ m.cpp</code> works, but in this case the executable is linked to <code>libstdc++</code>.</p>