Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unable to reproduce memory sanitization results from the project's example project

I'm getting exactly the same results from centos7, clang-3.6.1 built from source using a fedora rpm specfile. Ubuntu 14.04, clang-3.4

Using the instructions from the wiki here https://github.com/google/sanitizers/wiki/MemorySanitizerLibcxxHowTo as closely as possible. The page was last updated 6 months ago.

googlest revision 613 is still using tr1

In file included from /home/hal/googletest/src/gtest-all.cc:39:
In file included from /home/hal/googletest/include/gtest/gtest.h:58:
In file included from /home/hal/googletest/include/gtest/internal/gtest-internal.h:40:
/home/hal/googletest/include/gtest/internal/gtest-port.h:507:13: fatal error: 
      'tr1/tuple' file not found
#   include <tr1/tuple>  // NOLINT
            ^
1 error generated.

update googletest to tip (746) and it compiles with the following warning

➜ [hal@davis 9:54 ~/gtest-msan] make
Scanning dependencies of target gtest
[ 50%] Building CXX object CMakeFiles/gtest.dir/src/gtest-all.cc.o
clang: warning: -lc++abi: 'linker' input unused
clang: warning: -lc++abi: 'linker' input unused
clang: warning: argument unused during compilation: '-L/home/hal/libcxx_msan/lib'
clang: warning: argument unused during compilation: '-L/home/hal/libcxx_msan/lib'
Linking CXX static library libgtest.a

And the trivial suggested case from that page didn't get picked up by msan

[==========] Running 1 test from 1 test case.
[----------] Global test environment set-up.
[----------] 1 test from FooTest
[ RUN      ] FooTest.Foo
test.cc:7: Failure
Value of: foo[4]
  Actual: '\0'
Expected: 'z'
Which is: 'z' (122, 0x7A)
[  FAILED  ] FooTest.Foo (1 ms)
[----------] 1 test from FooTest (1 ms total)

[----------] Global test environment tear-down
[==========] 1 test from 1 test case ran. (1 ms total)
[  PASSED  ] 0 tests.
[  FAILED  ] 1 test, listed below:
[  FAILED  ] FooTest.Foo

 1 FAILED TEST

I have a project where valgrind barfs due to using some very large mmaps so memory sanitization would be really useful. If I'm doing something wrong. It appears that googletest suppresses the error somehow. Removing google test and converting the test case to

if(foo[4] == 'z') std::cout << "it is z" << std::endl;

Triggers the reporting of the obvious error as expected

==29128== WARNING: MemorySanitizer: use-of-uninitialized-value
    #0 0x7f59270c1738 in std::string::_Rep::_M_is_leaked() const /usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../include/c++/4.8.5/bits/basic_string.h:192:18
    #1 0x7f59270c1738 in std::string::_M_leak() /usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../include/c++/4.8.5/bits/basic_string.h:316
    #2 0x7f59270c1738 in std::string::operator[](unsigned long) /usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../include/c++/4.8.5/bits/basic_string.h:849
    #3 0x7f59270c1738 in main /home/hal/test-gtest-msan/test2.cc:7
    #4 0x7f5925c2bb14 in __libc_start_main (/lib64/libc.so.6+0x21b14)
    #5 0x7f592706ce30 in _start (/home/hal/test-gtest-msan/test2+0x35e30)

  Uninitialized value was created by an allocation of 'foo' in the stack frame of function 'main'
    #0 0x7f59270c12e0 in main /home/hal/test-gtest-msan/test2.cc:4

SUMMARY: MemorySanitizer: use-of-uninitialized-value /usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../include/c++/4.8.5/bits/basic_string.h:192 std::string::_Rep::_M_is_leaked() const
Exiting

Is it possible to use memory sanitization with a unit test library?

like image 852
Hal Avatar asked Jan 07 '16 23:01

Hal


1 Answers

It's not MemorySanitizer or googletest problem: apparently libc++ has changed recently, and now it initializes bytes outside of the actual four-byte string "foo", so MSan is not producing the report for this out-of-bound access.

MSan wiki has been updated to use a different example, for which the error is reported as expected:

TEST(FooTest, Foo) {
  int uninitialized;
  EXPECT_GT(uninitialized, 5);
}

results in:

[==========] Running 1 test from 1 test case.
[----------] Global test environment set-up.
[----------] 1 test from FooTest
[ RUN      ] FooTest.Foo
==39032== WARNING: MemorySanitizer: use-of-uninitialized-value
    #0 0x48d73c in testing::AssertionResult testing::internal::CmpHelperGT<int, int>(char const*, char const*, int const&, int const&) googletest/include/gtest/gtest.h:1463:1
    #1 0x48ce7a in FooTest_Foo_Test::TestBody() test.cc:6:3
...

P.S. You can add -DGTEST_USE_OWN_TR1_TUPLE=1 to compile flags when you configure googletest to build it at revision 613.

like image 167
vonosmas Avatar answered Nov 13 '22 18:11

vonosmas