EXPECT_CALL 简单情况下的 googlemock 分段错误
googlemock segmentation fault with simple case of EXPECT_CALL
模拟 class:
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");
}
gdb 中的堆栈捕获:
Catchpoint 1 (signal SIGSEGV), 0x00005555557266f6 in testing::Cardinality::ConservativeUpperBound() const ()
(gdb) bt
#0 0x00005555557266f6 in testing::Cardinality::ConservativeUpperBound() const ()
#1 0x00005555557216c9 in testing::internal::ExpectationBase::CheckActionCountIfNotDone() const ()
#2 0x00005555556ba810 in testing::internal::TypedExpectation<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)>::ShouldHandleArguments(std::tuple<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&> const&) const (this=0x555555a2c8a0, args=std::tuple containing = {...})
at /home/phillip/.conan/data/googletest/1.8.1/phillip/stable/package/efbe354690ef83824a1e98c7a6076b7ab63bc1b3/include/gmock/gmock-spec-builders.h:1111
#3 0x00005555556b9749 in testing::internal::FunctionMockerBase<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)>::FindMatchingExpectationLocked(std::tuple<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&> const&) const (this=0x7fffffffda00, args=std::tuple containing = {...})
at /home/phillip/.conan/data/googletest/1.8.1/phillip/stable/package/efbe354690ef83824a1e98c7a6076b7ab63bc1b3/include/gmock/gmock-spec-builders.h:1739
#4 0x00005555556b8b56 in testing::internal::FunctionMockerBase<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)>::UntypedFindMatchingExpectation(void const*, void const**, bool*, std::ostream*, std::ostream*) (this=0x7fffffffda00, untyped_args=0x7fffffffd8f0, untyped_action=0x7fffffffd340, is_excessive=0x7fffffffd337, what=0x7fffffffd3d0, why=0x7fffffffd560)
at /home/phillip/.conan/data/googletest/1.8.1/phillip/stable/package/efbe354690ef83824a1e98c7a6076b7ab63bc1b3/include/gmock/gmock-spec-builders.h:1701
#5 0x000055555572235d in testing::internal::UntypedFunctionMockerBase::UntypedInvokeWith(void*) ()
#6 0x00005555556b56c0 in testing::internal::FunctionMockerBase<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)>::InvokeWith(std::tuple<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&>&&) (this=0x7fffffffda00, args=...) at /home/phillip/.conan/data/googletest/1.8.1/phillip/stable/package/efbe354690ef83824a1e98c7a6076b7ab63bc1b3/include/gmock/gmock-spec-builders.h:1602
#7 0x00005555556b4b75 in testing::internal::FunctionMocker<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)>::Invoke(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (this=0x7fffffffda00, a1="1") at /home/phillip/.conan/data/googletest/1.8.1/phillip/stable/package/efbe354690ef83824a1e98c7a6076b7ab63bc1b3/include/gmock/gmock-generated-function-mockers.h:101
#8 0x00005555556b46f0 in MockManagerForClient::RemoveClient (this=0x7fffffffd9b0, gmock_a1=...) at /home/phillip/projects/spiral-front/front/engine-test/src/client-impl/./mocks.hpp:33
#9 0x00005555556b3480 in ClientTest_Login_Test::TestBody (this=0x555555a2c1c0) at /home/phillip/projects/spiral-front/front/engine-test/src/client-impl/client-impl-test.cpp:43
#10 0x000055555575f371 in void testing::internal::HandleSehExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) ()
#11 0x000055555575957b in void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) ()
#12 0x0000555555739298 in testing::Test::Run() ()
#13 0x0000555555739bf5 in testing::TestInfo::Run() ()
#14 0x000055555573a278 in testing::TestCase::Run() ()
#15 0x0000555555745064 in testing::internal::UnitTestImpl::RunAllTests() ()
#16 0x0000555555760519 in bool testing::internal::HandleSehExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool>(testing::internal::UnitTestImpl*, bool (testing::internal::UnitTestImpl::*)(), char const*) ()
#17 0x000055555575a35f in bool testing::internal::HandleExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool>(testing::internal::UnitTestImpl*, bool (testing::internal::UnitTestImpl::*)(), char const*) ()
#18 0x0000555555743aec in testing::UnitTest::Run() ()
#19 0x00005555556fe830 in RUN_ALL_TESTS () at /home/phillip/.conan/data/googletest/1.8.1/phillip/stable/package/efbe354690ef83824a1e98c7a6076b7ab63bc1b3/include/gtest/gtest.h:2341
#20 0x00005555556fe23c in main (argc=1, argv=0x7fffffffe148) at /home/phillip/projects/spiral-front/front/engine-test/src/main.cpp:7
我已经尝试了几个小时,但不知道为什么。我还有其他几个mockclass,所有作品都找得到。这个MockManagerForClient最不同的是RemoveClient是returnvoid.
我终于在 2 天后解决了这个问题。就像其他人的崩溃情况一样,这是由于项目的编译标志与googletest不同。
我的环境是 Ubuntu 18.04 和 g++ 7.4.0。
为了使 googletest 使用 c++11
标准,我使用 https://github.com/google/googletest 的主分支。使用 cmake 构建 googletest 并检查 cmake 生成文件:flags.make
googletest 使用 -std=c++11
,我的项目会使用 -std=gun++11
。所以添加以下 cmake 定义:
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
修复了由于使用 c++14 功能而导致的编译错误。那么崩溃问题依然存在
不在我的项目中的额外编译标志是:-g -Wall -Wshadow -Werror -Wno-error=dangling-else -DGTEST_HAS_PTHREAD=1 -fexceptions -Wextra -Wno-unused-parameter -Wno-missing-field-initializers
将它们添加到我的项目的 CMakeLists.txt 并修复编译错误后。 googletest 崩溃问题终于解决了。
模拟 class:
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");
}
gdb 中的堆栈捕获:
Catchpoint 1 (signal SIGSEGV), 0x00005555557266f6 in testing::Cardinality::ConservativeUpperBound() const ()
(gdb) bt
#0 0x00005555557266f6 in testing::Cardinality::ConservativeUpperBound() const ()
#1 0x00005555557216c9 in testing::internal::ExpectationBase::CheckActionCountIfNotDone() const ()
#2 0x00005555556ba810 in testing::internal::TypedExpectation<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)>::ShouldHandleArguments(std::tuple<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&> const&) const (this=0x555555a2c8a0, args=std::tuple containing = {...})
at /home/phillip/.conan/data/googletest/1.8.1/phillip/stable/package/efbe354690ef83824a1e98c7a6076b7ab63bc1b3/include/gmock/gmock-spec-builders.h:1111
#3 0x00005555556b9749 in testing::internal::FunctionMockerBase<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)>::FindMatchingExpectationLocked(std::tuple<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&> const&) const (this=0x7fffffffda00, args=std::tuple containing = {...})
at /home/phillip/.conan/data/googletest/1.8.1/phillip/stable/package/efbe354690ef83824a1e98c7a6076b7ab63bc1b3/include/gmock/gmock-spec-builders.h:1739
#4 0x00005555556b8b56 in testing::internal::FunctionMockerBase<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)>::UntypedFindMatchingExpectation(void const*, void const**, bool*, std::ostream*, std::ostream*) (this=0x7fffffffda00, untyped_args=0x7fffffffd8f0, untyped_action=0x7fffffffd340, is_excessive=0x7fffffffd337, what=0x7fffffffd3d0, why=0x7fffffffd560)
at /home/phillip/.conan/data/googletest/1.8.1/phillip/stable/package/efbe354690ef83824a1e98c7a6076b7ab63bc1b3/include/gmock/gmock-spec-builders.h:1701
#5 0x000055555572235d in testing::internal::UntypedFunctionMockerBase::UntypedInvokeWith(void*) ()
#6 0x00005555556b56c0 in testing::internal::FunctionMockerBase<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)>::InvokeWith(std::tuple<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&>&&) (this=0x7fffffffda00, args=...) at /home/phillip/.conan/data/googletest/1.8.1/phillip/stable/package/efbe354690ef83824a1e98c7a6076b7ab63bc1b3/include/gmock/gmock-spec-builders.h:1602
#7 0x00005555556b4b75 in testing::internal::FunctionMocker<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)>::Invoke(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (this=0x7fffffffda00, a1="1") at /home/phillip/.conan/data/googletest/1.8.1/phillip/stable/package/efbe354690ef83824a1e98c7a6076b7ab63bc1b3/include/gmock/gmock-generated-function-mockers.h:101
#8 0x00005555556b46f0 in MockManagerForClient::RemoveClient (this=0x7fffffffd9b0, gmock_a1=...) at /home/phillip/projects/spiral-front/front/engine-test/src/client-impl/./mocks.hpp:33
#9 0x00005555556b3480 in ClientTest_Login_Test::TestBody (this=0x555555a2c1c0) at /home/phillip/projects/spiral-front/front/engine-test/src/client-impl/client-impl-test.cpp:43
#10 0x000055555575f371 in void testing::internal::HandleSehExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) ()
#11 0x000055555575957b in void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) ()
#12 0x0000555555739298 in testing::Test::Run() ()
#13 0x0000555555739bf5 in testing::TestInfo::Run() ()
#14 0x000055555573a278 in testing::TestCase::Run() ()
#15 0x0000555555745064 in testing::internal::UnitTestImpl::RunAllTests() ()
#16 0x0000555555760519 in bool testing::internal::HandleSehExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool>(testing::internal::UnitTestImpl*, bool (testing::internal::UnitTestImpl::*)(), char const*) ()
#17 0x000055555575a35f in bool testing::internal::HandleExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool>(testing::internal::UnitTestImpl*, bool (testing::internal::UnitTestImpl::*)(), char const*) ()
#18 0x0000555555743aec in testing::UnitTest::Run() ()
#19 0x00005555556fe830 in RUN_ALL_TESTS () at /home/phillip/.conan/data/googletest/1.8.1/phillip/stable/package/efbe354690ef83824a1e98c7a6076b7ab63bc1b3/include/gtest/gtest.h:2341
#20 0x00005555556fe23c in main (argc=1, argv=0x7fffffffe148) at /home/phillip/projects/spiral-front/front/engine-test/src/main.cpp:7
我已经尝试了几个小时,但不知道为什么。我还有其他几个mockclass,所有作品都找得到。这个MockManagerForClient最不同的是RemoveClient是returnvoid.
我终于在 2 天后解决了这个问题。就像其他人的崩溃情况一样,这是由于项目的编译标志与googletest不同。
我的环境是 Ubuntu 18.04 和 g++ 7.4.0。
为了使 googletest 使用 c++11
标准,我使用 https://github.com/google/googletest 的主分支。使用 cmake 构建 googletest 并检查 cmake 生成文件:flags.make
googletest 使用 -std=c++11
,我的项目会使用 -std=gun++11
。所以添加以下 cmake 定义:
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
修复了由于使用 c++14 功能而导致的编译错误。那么崩溃问题依然存在
不在我的项目中的额外编译标志是:-g -Wall -Wshadow -Werror -Wno-error=dangling-else -DGTEST_HAS_PTHREAD=1 -fexceptions -Wextra -Wno-unused-parameter -Wno-missing-field-initializers
将它们添加到我的项目的 CMakeLists.txt 并修复编译错误后。 googletest 崩溃问题终于解决了。