You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用GoogleTest死亡测试时遭遇AddressSanitizer:DEADLYSIGNAL问题求助

解决AddressSanitizer与GoogleTest ASSERT_EXIT预期SIGSEGV冲突的问题

我之前在项目里也碰到过一模一样的情况!当开启AddressSanitizer(ASan)后,它会抢先捕获SIGSEGV这类致命信号,生成错误报告并直接终止程序,导致GoogleTest的ASSERT_EXIT没法正确识别这个预期的退出场景,最终测试失败。下面是几种实用的解决办法,你可以根据自己的场景选择:

方法一:在测试代码中临时禁用ASan的信号处理

直接在ASSERT_EXIT的代码块里,调用ASan的内部API关闭它的致命信号回调,让GTest能正常捕获SIGSEGV:

ASSERT_EXIT(
    {
        // 临时关闭ASan的致命信号处理回调
        __asan_set_death_callback(nullptr);
        // 这里放你触发SIGSEGV的测试代码
        int* null_ptr = nullptr;
        *null_ptr = 42;
    },
    ::testing::KilledBySignal(SIGSEGV),
    ".*"
);

注意:__asan_set_death_callback是ASan的内部API,主流编译器(GCC/Clang)都支持,但如果ASan版本更新,可能存在兼容性风险,不过大部分场景下都能正常工作。

方法二:临时修改ASan环境变量

如果不想依赖内部API,可以在单个测试用例中临时设置ASAN_OPTIONS环境变量,关闭致命信号检测,测试完成后再恢复:

TEST(ErrorHandlingTest, ExpectedSegv) {
    // 保存原有的ASAN_OPTIONS配置
    const char* original_asan_opts = getenv("ASAN_OPTIONS");
    
    // 设置新的选项:关闭致命信号检测
    setenv("ASAN_OPTIONS", "detect_deadly_signals=0", 1);

    ASSERT_EXIT(
        {
            // 触发预期的SIGSEGV
            int* p = nullptr;
            *p = 0;
        },
        ::testing::KilledBySignal(SIGSEGV),
        ".*"
    );

    // 恢复原来的环境变量配置
    if (original_asan_opts) {
        setenv("ASAN_OPTIONS", original_asan_opts, 1);
    } else {
        unsetenv("ASAN_OPTIONS");
    }
}

这种方法更通用,不依赖ASan的内部接口,适合需要保持代码兼容性的场景。

方法三:在构建系统中为单个测试设置环境变量

如果用CMake管理项目,可以直接给这个特定的测试目标单独配置环境变量,不用修改测试代码:

add_test(NAME ExpectedSegvTest COMMAND YourTestExecutable)
set_tests_properties(ExpectedSegvTest PROPERTIES
    ENVIRONMENT "ASAN_OPTIONS=detect_deadly_signals=0"
)

这个方法的好处是不会侵入测试代码,只针对需要的测试生效,其他测试依然能享受ASan的完整检测能力。

为什么会出现这个问题?

ASan默认会拦截SIGSEGV、SIGABRT等致命信号,目的是生成详细的内存错误报告。但这个拦截会先于GoogleTest的信号处理逻辑执行,导致GTest无法检测到程序是被预期的SIGSEGV杀死的,最终判定测试失败。通过上面的方法关闭ASan对致命信号的检测,就能让GTest正常处理预期的崩溃场景了。

内容的提问来源于stack exchange,提问作者Mohammed Li

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 16:40:52