dolev ben
dolev ben

Reputation: 23

Suppress unitest of gtest for Address sanitizer

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

Answers (2)

tokrelo
tokrelo

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

Employed Russian
Employed Russian

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

Related Questions