【问题标题】:Trigger a test failure when UBSAN (-fsanitize=undefined) finds undefined behaviour当 UBSAN (-fsanitize=undefined) 发现未定义行为时触发测试失败
【发布时间】:2021-08-02 15:46:06
【问题描述】:

我在这里有一个未定义行为的小型单元测试。

源代码:

#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 发现问题时,是否可能触发测试失败(抛出异常、退出 1 等)?

【问题讨论】:

  • 也许你可以重定向标准输出(或者它是标准错误?)并断言。

标签: c++ ubsan


【解决方案1】:

根据documentation

  • -fsanitize=...:打印详细的错误报告并继续执行(默认);

  • -fno-sanitize-recover=...:打印详细的错误报告并退出程序;

  • -fsanitize-trap=...:执行陷阱指令(不需要 UBSan 运行时支持)。

请注意,trap / recover 选项不启用相应的消毒剂,通常需要伴随一个合适的-fsanitize= 标志。

似乎当您使用-fsanitize= 时,会发生与您所说的完全相同的事情。它注意到未定义的行为并报告它,但继续执行。所以附加一个-fno-sanitize-recover=all 应该会退出程序。

【讨论】:

  • 哈-RTFM!谢谢!看起来正确的方法是添加 -fno-sanitize-recover=all(即:除了-fsantize=undefined
  • @SteveLorimer 啊我明白了,可能是由于 "注意陷阱/恢复选项不启用相应的消毒剂,一般需要伴随一个合适的-fsanitize= 标志。”我会编辑我的帖子来解决这个问题。
【解决方案2】:

你可以试试UBSAN_OPTIONS="halt_on_error=1"环境变量。

UBSAN_OPTIONS="halt_on_error=1" cmake --build cmake-build-UBSAN --target test

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-14
    • 2019-06-18
    • 1970-01-01
    • 1970-01-01
    • 2016-09-18
    • 1970-01-01
    相关资源
    最近更新 更多