Reputation: 23
I'm running Address sanitizer on my unitests. Cmake looks something like this:
cmake -G"Unix Makefiles" \
-DCMAKE_CXX_COMPILER=clang++-9 \
-DCMAKE_C_COMPILER=clang-9 \
-DCMAKE_C_FLAGS='-fsanitize=address -fsanitize-address-use-after-scope' \
-DCMAKE_CXX_FLAGS='-fsanitize=address -fsanitize-address-use-after-scope' \
The running command is
make clean
ASAN_OPTIONS=detect_stack_use_after_return=1 make a.out -j
ASAN_OPTIONS=detect_stack_use_after_return=1 LSAN_OPTIONS=verbosity=1 ./a.out
The unitests are written in gtest framework.
There is some unitest that by definition should make illegal access to out of array boundaries. And I want to know how I can suppress this test
TEST_F(classA, testA) {
some_struct a;
a.p = 100;
ASSERT_FALSE(&foo());
}
I saw here the option to suppress function but I don't know how to apply it on a unitest function https://github.com/google/sanitizers/wiki/AddressSanitizer
#if defined(__clang__) || defined (__GNUC__)
# define ATTRIBUTE_NO_SANITIZE_ADDRESS __attribute__((no_sanitize_address))
#else
# define ATTRIBUTE_NO_SANITIZE_ADDRESS
#endif
...
ATTRIBUTE_NO_SANITIZE_ADDRESS
void ThisFunctionWillNotBeInstrumented() {...}
Upvotes: 2
Views: 1469
Reputation: 1
You should not have a test like this.
Accessing an array out of bounds is undefined behaviour. That means exaclty what the term suggests - the behaviour is undefined. You should not provoke undefined behaviour, not even in a test. It is likely that nothing bad will happen, but you are not guaranteed, as anything could happen: your program might crash, the program might continue to run the other tests with corrupted data, ...
But even more importantly, the result of your test is undefined. So if the test passes or fails, it doesn't tell you anything about your program!
Upvotes: 0
Reputation: 213829
how I can suppress this test
The easiest approach is probably to #ifdef
it out:
TEST_F(classA, testA) {
#if defined(__SANITIZE_ADDRESS__)
std::cerr << "classA.testA skipped under AddressSanitizer" << std::endl;
#else
some_struct a;
a.p = 100;
ASSERT_FALSE(&foo());
#endif
}
Or you could #ifdef
out the entire test:
#if !defined(__SANITIZE_ADDRESS__)
TEST_F(classA, testA) {
std::cerr << "classA.testA skipped under AddressSanitizer" << std::endl;
some_struct a;
a.p = 100;
ASSERT_FALSE(&foo());
}
#endif
Upvotes: 1