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

GoogleMock使用EXPECT_CALL与Mock类触发段错误求助

GoogleMock Void方法调用时出现段错误的排查方案

我之前也遇到过类似的GoogleMock段错误问题,结合你提供的代码和栈信息,咱们来一步步分析可能的原因和解决办法:

问题场景回顾

你的Mock类和测试用例逻辑上看起来没问题:

// Mock类定义
class MockManagerForClient {
public:
    MOCK_CONST_METHOD0(GetEngine, std::shared_ptr<engine::Engine>());
    MOCK_METHOD1(RemoveClient, void(std::string const& clientId));
    virtual ~MockManagerForClient() = default;
};

// 测试用例
TEST(ClientTest, Login) {
    NiceMock<MockManagerForClient> manager;
    EXPECT_CALL(manager, RemoveClient(_)).Times(1);
    manager.RemoveClient("1");
}

但调用RemoveClient时触发了段错误,栈信息指向testing::Cardinality::ConservativeUpperBound(),说明GoogleMock在检查调用次数的内部逻辑中访问了无效内存。

可能的原因及解决办法

1. C++标准库ABI兼容性问题

从栈里的std::__cxx11::basic_string可以看出,你的测试代码用了C11及以上的标准库,但如果你的GoogleMock 1.8.1是用旧标准(比如C98)编译的,或者编译时_GLIBCXX_USE_CXX11_ABI宏的设置和测试代码不一致,就会导致std::string的内存布局不匹配,进而引发段错误。

解决步骤:

  • 确认编译GoogleMock和测试代码时使用相同的C++标准(比如都加-std=c++11或更高)。
  • 检查_GLIBCXX_USE_CXX11_ABI宏的设置:GCC 5及以上默认开启,旧版本需要手动指定-D_GLIBCXX_USE_CXX11_ABI=1,确保两边设置一致。
  • 优先升级GoogleMock到1.10.0或最新版本,新版本对C++11+的兼容性好很多,这类ABI问题基本都被修复了。

2. GoogleMock 1.8.1的已知Bug

1.8.1版本确实存在一些关于void方法Expectation的小Bug,比如Times(1)的内部Cardinality对象初始化可能存在问题。

临时规避方案:

  • 把Times(1)换成Exactly(1)(两者语义完全相同,但内部实现细节有差异),看看能不能绕过这个Bug。
  • 暂时去掉NiceMock,改用普通的MockManagerForClient,排除NiceMock的特殊处理逻辑带来的影响。

3. Mock类编译一致性问题

如果你的Mock类头文件和测试代码的编译选项不一致(比如优化级别、宏定义不同),可能会破坏虚函数表的正确性,导致调用Mock方法时访问无效内存。

解决步骤:

  • 确保Mock类的头文件被正确包含,并且编译Mock类和测试代码时使用完全相同的编译选项。
  • 尝试把Mock类的定义直接放到测试文件里,排除头文件包含带来的编译差异。

4. 内存损坏问题

如果测试用例之前的代码存在内存越界、使用已释放内存等问题,可能会破坏GoogleMock内部的栈结构,导致后续操作触发段错误。

排查步骤:

  • 单独运行这个测试用例,看看是否还会出现错误,排除其他测试用例的影响。
  • 用Valgrind等内存检测工具运行测试,检查是否存在内存违规操作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 09:22:41