3

I'm using manjaro linux on x86-64. Memory-sanitizer in clang version 10.0.1 reported a use of uninitialized value error in std::map, which quite surprised me. Did I do something wrong?

$ cat test.cpp 
#include <map>
int main() {
    std::map<int, int> test;
    test.insert({1,2});
}
$ clang++ -fsanitize=memory test.cpp && ./a.out
==51936==WARNING: MemorySanitizer: use-of-uninitialized-value
    #0 0x562889eaad9a  (/tmp/build/a.out+0x9fd9a)
    #1 0x562889eaae28  (/tmp/build/a.out+0x9fe28)
    #2 0x562889eaaba1  (/tmp/build/a.out+0x9fba1)
    #3 0x562889eaa51e  (/tmp/build/a.out+0x9f51e)
    #4 0x562889eaa087  (/tmp/build/a.out+0x9f087)
    #5 0x7f418e02b151  (/usr/lib/libc.so.6+0x28151)
    #6 0x562889e2b1dd  (/tmp/build/a.out+0x201dd)

SUMMARY: MemorySanitizer: use-of-uninitialized-value (/tmp/build/a.out+0x9fd9a) 
Exiting
Deduplicator
  • 44,692
  • 7
  • 66
  • 118
Pac
  • 167
  • 4
  • 2
    The exact version of clang used would be useful to know. – Deduplicator Sep 17 '20 at 23:55
  • clang version 10.0.1 Target: x86_64-pc-linux-gnu Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-pc-linux-gnu/10.2.0 – Pac Sep 18 '20 at 00:02
  • 1
    Checkers like this can have false positives, where the uninitialized value doesn't actually affect the program's behavior but the checker can't determine that. I believe they try to have a list of known false positives from library code, which the checker is supposed to ignore, but they may have missed one. – Nate Eldredge Sep 18 '20 at 00:16

2 Answers2

0

FWIW it looks like libc++ is more MSAN-friendly than stdlibc++ because compiling a similar

#include <map>
#include <string>

int main(int argc, char** argv) {
    std::map<int, std::string> m;
    m[argc] = argv[argc - 1];
    return 0;
}

code with the latter and running

% clang++ -fsanitize=memory -fno-omit-frame-pointer -g -O2 umr.cpp

results in a similar error, but doing

% clang++ -fsanitize=memory -fno-omit-frame-pointer -stdlib=libc++ -g -O2 umr.cpp && ./a.out

works fine (clang 13, Debian Sid).

VZ.
  • 21,740
  • 3
  • 39
  • 42
  • Part of std::map is compiled into libstdc++.so and thus does not get recompiled with `-fsanitize=memory`, that probably doesn't help. – Marc Glisse Jan 14 '22 at 18:01
  • Yes, this makes sense, but somehow (because MSAN has some built-in knowledge about it? because libc++ had been tweaked to avoid MSAN errors?) this does work with libc++, even though it must also contain some part of `std::map`. – VZ. Jan 14 '22 at 21:22
  • libc++ puts more stuff in headers and less in a shared library, that's all. – Marc Glisse Jan 14 '22 at 23:45
0

When using MemorySanitizer, all libraries you use must be compiled with MemorySanitizer. Otherwise, there is a risk of false positives. This includes the C++ standard library itself.

You will find instructions for compiling libc++ with MemorySanitizer in the official sanitizers wiki:

https://github.com/google/sanitizers/wiki/MemorySanitizerLibcxxHowTo

Szabolcs
  • 24,728
  • 9
  • 85
  • 174