当 UBSAN (-fsanitize=undefined) 发现未定义行为时触发测试失败
Trigger a test failure when UBSAN (-fsanitize=undefined) finds undefined behaviour
我这里有一个小的单元测试,它有未定义的行为。
源代码:
#include <gtest/gtest.h>
TEST(test, test)
{
int k = 0x7fffffff;
k += 1; // cause integer overflow
}
GTEST_API_ int main(int argc, char** argv)
{
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
我在 CMakeLists.txt:
中启用了 UBSAN
cmake_minimum_required (VERSION 3.12)
project(ub CXX)
find_package(GTest REQUIRED)
add_executable (ub_test ub_test.cpp)
target_link_libraries (ub_test GTest::GTest)
target_compile_options(ub_test PRIVATE -fsanitize=undefined)
target_link_options (ub_test PRIVATE -fsanitize=undefined)
UBSAN 正确识别未定义的行为:
/home/steve/src/ub/ub_test.cpp:6:7: runtime error: signed integer overflow:
2147483647 + 1 cannot be represented in type 'int'
但是,我的测试还是通过了。
[==========] Running 1 test from 1 test suite.
[----------] Global test environment set-up.
[----------] 1 test from test
[ RUN ] test.test
/home/steve/src/ub/ub_test.cpp:6:7: runtime error: signed integer overflow:
2147483647 + 1 cannot be represented in type 'int'
[ OK ] test.test (0 ms)
[----------] 1 test from test (0 ms total)
[----------] Global test environment tear-down
[==========] 1 test from 1 test suite ran. (0 ms total)
[ PASSED ] 1 test.
UBSAN发现问题时是否可以触发测试失败(抛出异常,exit 1等)?
根据 documentation:
-fsanitize=...
: print a verbose error report and continue execution (default);
-fno-sanitize-recover=...
: print a verbose error report and exit the program;
-fsanitize-trap=...
: execute a trap instruction (doesn’t require UBSan run-time support).
Note that the trap
/ recover
options do not enable the corresponding sanitizer, and in general need to be accompanied by a suitable -fsanitize=
flag.
当您使用 -fsanitize=
时,似乎会发生与您所说的完全相同的事情。它注意到未定义的行为并报告它,但继续执行。所以附加一个 -fno-sanitize-recover=all
应该退出程序。
你可以试试UBSAN_OPTIONS="halt_on_error=1"
环境变量。
UBSAN_OPTIONS="halt_on_error=1" cmake --build cmake-build-UBSAN --target test
我这里有一个小的单元测试,它有未定义的行为。
源代码:
#include <gtest/gtest.h>
TEST(test, test)
{
int k = 0x7fffffff;
k += 1; // cause integer overflow
}
GTEST_API_ int main(int argc, char** argv)
{
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
我在 CMakeLists.txt:
中启用了 UBSANcmake_minimum_required (VERSION 3.12)
project(ub CXX)
find_package(GTest REQUIRED)
add_executable (ub_test ub_test.cpp)
target_link_libraries (ub_test GTest::GTest)
target_compile_options(ub_test PRIVATE -fsanitize=undefined)
target_link_options (ub_test PRIVATE -fsanitize=undefined)
UBSAN 正确识别未定义的行为:
/home/steve/src/ub/ub_test.cpp:6:7: runtime error: signed integer overflow: 2147483647 + 1 cannot be represented in type 'int'
但是,我的测试还是通过了。
[==========] Running 1 test from 1 test suite. [----------] Global test environment set-up. [----------] 1 test from test [ RUN ] test.test /home/steve/src/ub/ub_test.cpp:6:7: runtime error: signed integer overflow: 2147483647 + 1 cannot be represented in type 'int' [ OK ] test.test (0 ms) [----------] 1 test from test (0 ms total) [----------] Global test environment tear-down [==========] 1 test from 1 test suite ran. (0 ms total) [ PASSED ] 1 test.
UBSAN发现问题时是否可以触发测试失败(抛出异常,exit 1等)?
根据 documentation:
-fsanitize=...
: print a verbose error report and continue execution (default);
-fno-sanitize-recover=...
: print a verbose error report and exit the program;
-fsanitize-trap=...
: execute a trap instruction (doesn’t require UBSan run-time support).Note that the
trap
/recover
options do not enable the corresponding sanitizer, and in general need to be accompanied by a suitable-fsanitize=
flag.
当您使用 -fsanitize=
时,似乎会发生与您所说的完全相同的事情。它注意到未定义的行为并报告它,但继续执行。所以附加一个 -fno-sanitize-recover=all
应该退出程序。
你可以试试UBSAN_OPTIONS="halt_on_error=1"
环境变量。
UBSAN_OPTIONS="halt_on_error=1" cmake --build cmake-build-UBSAN --target test