Невозможно воспроизвести результаты очистки памяти из примера проекта

Я получаю точно такие же результаты от centos7, clang-3.6.1, созданного из исходного кода с использованием специфицированного файла Fedora rpm. Ubuntu 14.04, clang-3.4

Используя инструкции из вики здесь https://github.com/google/sanitizers/wiki/MemorySanitizerLibcxxHowTo
как можно ближе. Эта страница была последний раз обновлена ​​6 месяцев назад.

Версия Google 613 все еще использует 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.

обновите googletest до tip (746), и он скомпилирует следующее предупреждение

➜ [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

И тривиальный предложенный случай с этой страницы не был подхвачен 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

У меня есть проект, где valgrind barfs из-за использования очень больших mmaps, чтобы очистка памяти была бы действительно полезной. Если я делаю что-то не так. Похоже, что googletest как-то подавляет ошибку. Удаление теста Google и преобразование теста в

if (foo [4] == ‘z’)
станд :: соиЬ << «это г» << станд :: епсИ;

Запускает сообщение об очевидной ошибке, как и ожидалось

==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

Можно ли использовать очистку памяти с библиотекой юнит-тестов?

6

Решение

Это не MemorySanitizer и не проблема googletest: очевидно, libc ++ недавно изменилась, и теперь она инициализирует байты за пределами фактической четырехбайтовой строки «foo», поэтому MSan не создает отчет для этого внешнего доступа.

MSan Wiki был обновлен для использования другого примера, для которого ошибка сообщается, как и ожидалось:

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

результаты в:

[==========] 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
...

Постскриптум Можете добавить -DGTEST_USE_OWN_TR1_TUPLE=1 скомпилировать флаги, когда вы настраиваете googletest, чтобы собрать его в ревизии 613.

3

Другие решения

Поскольку значение, показанное в вашем модульном тесте, равно '\0' могло случиться так, что строка фактически инициализировала память в позиции 4, чтобы быть совместимой с C-строкой (конечный ноль). Разница между модульным тестом и вашим ручным тестовым примером может быть результатом оптимизации компилятора. Что произойдет, если вы переключите строку на std::vector<char>{'f', 'o', 'o'}?

Было бы полезно, если бы вы также могли опубликовать код модульного теста.

0

По вопросам рекламы [email protected]