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
相关产品推荐
相关产品推荐

