在 cygwin 上,EXPECT_CALL 给出分段错误。回溯显示:
Program received signal SIGSEGV, Segmentation fault.
0x004538e2 in join (ptr=0x61230494 <vtable for pthread_key+12>,
this=0x8003aedc) at ./gtest/include/gtest/internal/gtest-linked_ptr.h:113
113 while (p->next_ != ptr) p = p->next_;
(gdb) bt
#0 0x004538e2 in join (ptr=0x61230494 <vtable for pthread_key+12>,
this=0x8003aedc) at ./gtest/include/gtest/internal/gtest-linked_ptr.h:113
#1 copy<testing::internal::ExpectationBase> (
ptr=0x61230490 <vtable for pthread_key+8>, this=0x8003aed8)
at ./gtest/include/gtest/internal/gtest-linked_ptr.h:206
#2 linked_ptr (ptr=..., this=0x8003aed8)
at ./gtest/include/gtest/internal/gtest-linked_ptr.h:149
#3 Expectation (this=0x8003aed8) at ./include/gmock/gmock-spec-builders.h:487
...
(gdb) p ptr
$1 = (const testing::internal::linked_ptr_internal *) 0x61230494 <vtable for pthread_key+12>
(gdb) p p
$2 = (const testing::internal::linked_ptr_internal *) 0x18ec8353
(gdb) p p->next_
Cannot access memory at address 0x18ec8353
看起来像一些 gmock 内部链接列表损坏,但由于我的测试并不复杂,所以连接了:
模拟类:
class NSEBase {
public:
NSEBase(const std::string& ip, const std::string& port)
: ip_(ip), port_(port) { } ;
void setRequestHandler(RequestHandler& req_hdl) {
request_handler_ = &req_hdl;
};
virtual void send(Response& rsp) { };
virtual void run() { };
virtual ~NSEBase() { };
private:
RequestHandler * request_handler_;
const std::string & ip_, port_;
};
模拟类标题:
class NSEBaseMock : public NSEBase {
public:
NSEBaseMock(const char* ip, const char* port) : NSEBase(ip, port) {};
MOCK_METHOD0(run, void());
MOCK_METHOD1(send, void(Response& rsp));
};
模拟类主体:
class NSEBaseMockTest : public ::testing::Test {
protected:
static const std::string retrieve_json;
Request * req_;
Response * rsp_;
CSEBase * cse_;
NSEBaseMock * nse_;
CSEHandler * hdl_;
CSEServer * server_;
public:
virtual void SetUp()
{
....
nse_ = new NiceMock<NSEBaseMock>("127.0.0.1", "1234");
....
// cout shows it got here correctly
}
virtual void TearDown()
{
....
delete nse_;
....
}
void handleRequest() {
req_ = new Request(retrieve_json);
hdl_->handleRequest(*req_);
}
};
const string NSEBaseMockTest::retrieve_json(....);
TEST_F(NSEBaseMockTest, RetrieveCSE) {
EXPECT_CALL(*nse_, run()) **<--- crash here. no matter with .WillOnce or w/o.**
.WillOnce(Invoke(this, &NSEBaseMockTest::handleRequest));
std::cout << "EXPECT_CALL() done" << std::endl;
ON_CALL(*nse_, send(Property(&Response::getResponseStatusCode, Eq(RSC_OK))));
std::cout << "ON_CALL() done" << std::endl;
server_->run();
}
通过 gmock 论坛和这里搜索,还没有任何线索。直到今天我都在使用最新的。
请给我一些想法:)谢谢。
射线
抱歉,伊恩回复晚了。这是我的编译日志,所有 cc 文件的标志相同:
*g++ utest/gmock/NSEBase_mock.cc -Wall -D_WIN32_WINNT=0x0501 -D__USE_W32_SOCKETS -std=gnu++11 -Iinclude -Isrc -Istore -Isrc-gen -Icse -Iutest/gtest -I/cygdrive/c/Workspace/gmock-1.7.0/gtest/include -Iutest/gmock -I/cygdrive/c/Workspace/gmock-1.7.0/include -I/cygdrive/c/Workspace/gmock-1.7.0/gtest/include -g -c -o build/utest/gmock/NSEBase_mock.o*
链接命令:
*`g++ build/src/Request.o build/src/RequestHandler.o build/src/Response.o build/src/CSEBase.o build/store/FakeStore.o build/src-gen/Response.pb.o build/src-gen/CSEBase.pb.o build/src-gen/CommonTypes.pb.o build/src-gen/Request.pb.o build/cse/CSEServer.o build/cse/CSEHandler.o build/utest/gmock/NSEBase_mock.o build/utest/gmock/gmock_main.o -ljson2pb -ljansson -lprotobuf -lpthread -lboost_iostreams -lboost_filesystem -lboost_system -L/usr/local/lib -lgtest -L/cygdrive/c/Workspace/gmock-1.7.0/gtest/lib/.libs -lgmock -lgtest -L/cygdrive/c/Workspace/gmock-1.7.0/lib/.libs -L/cygdrive/c/Workspace/gmock-1.7.0/gtest/lib/.libs -lws2_32 -o build/gmock.exe`*
关于 NSEBase 中的 ip_, port_ 字符串引用,你是对的,但它还没有相关性,NSEBase 现在是一个存根,它仍然崩溃。
完整的崩溃调用跟踪:
Program received signal SIGSEGV, Segmentation fault.
0x00465002 in join (ptr=0x61230494 <vtable for pthread_key+12>,
this=0x8003e844) at ./gtest/include/gtest/internal/gtest-linked_ptr.h:113
113 while (p->next_ != ptr) p = p->next_;
(gdb) bt
#0 0x00465002 in join (ptr=0x61230494 <vtable for pthread_key+12>,
this=0x8003e844) at ./gtest/include/gtest/internal/gtest-linked_ptr.h:113
#1 copy<testing::internal::ExpectationBase> (
ptr=0x61230490 <vtable for pthread_key+8>, this=0x8003e840)
at ./gtest/include/gtest/internal/gtest-linked_ptr.h:206
#2 linked_ptr (ptr=..., this=0x8003e840)
at ./gtest/include/gtest/internal/gtest-linked_ptr.h:149
#3 Expectation (this=0x8003e840) at ./include/gmock/gmock-spec-builders.h:487
#4 construct (this=<optimized out>, __val=..., __p=0x8003e840)
at /usr/lib/gcc/i686-pc-cygwin/4.9.3/include/c++/ext/new_allocator.h:130
#5 _M_create_node (this=<optimized out>, __x=...)
at /usr/lib/gcc/i686-pc-cygwin/4.9.3/include/c++/bits/stl_tree.h:397
#6 _M_insert_ (__v=..., __p=0x8003e498, __x=0x0, this=0x8003e494)
at /usr/lib/gcc/i686-pc-cygwin/4.9.3/include/c++/bits/stl_tree.h:1143
#7 std::_Rb_tree<testing::Expectation, testing::Expectation, std::_Identity<testing::Expectation>, testing::Expectation::Less, std::allocator<testing::Expectation> >::_M_insert_unique (this=0x8003e494, __v=...)
at /usr/lib/gcc/i686-pc-cygwin/4.9.3/include/c++/bits/stl_tree.h:1503
#8 0x00437bd0 in insert (__x=..., this=<optimized out>)
at /usr/lib/gcc/i686-pc-cygwin/4.9.3/include/c++/bits/stl_set.h:502
#9 operator+= (e=..., this=<optimized out>)
at ./include/gmock/gmock-spec-builders.h:602
#10 testing::Sequence::AddExpectation (this=0x8003af20, expectation=...)
at ./src/gmock-spec-builders.cc:788
#11 0x00449511 in testing::internal::FunctionMockerBase<void ()>::AddNewExpectation(char const*, int, std::string const&, std::tuple<> const&) (
this=0x8003e188,
file=0x481bba <testing::_+104> "utest/gmock/NSEBase_mock.cc", line=74,
source_text=..., m=...)
at /cygdrive/c/Workspace/gmock-1.7.0/include/gmock/../../../gmock/include/gmock/../../../gmock/include/gmock/gmock-spec-builders.h:1560
#12 0x0044cf12 in testing::internal::MockSpec<void ()>::InternalExpectedAt(char const*, int, char const*, char const*) (this=0x8003e1ac,
file=0x481bba <testing::_+104> "utest/gmock/NSEBase_mock.cc", line=74,
obj=0x481bb4 <testing::_+98> "*nse_",
call=0x481bae <testing::_+92> "run()")
at /cygdrive/c/Workspace/gmock-1.7.0/include/gmock/../../../gmock/include/gmock/../../../gmock/include/gmock/gmock-spec-builders.h:1273
#13 0x0041432a in NSEBaseMockTest_RetrieveCSE_Test::TestBody (this=0x8003dd70)
at utest/gmock/NSEBase_mock.cc:74
#14 0x0044c45c in HandleSehExceptionsInMethodIfSupported<testing::Test, void> (
location=0x484c00 <(anonymous namespace)::b64_decode(std::string const&)::lookup+8000> "the test body",
method=&virtual table offset 16, this adjustment -2147230352,
---Type <return> to continue, or q <return> to quit---
object=0x8003dd70) at ./src/gtest.cc:2078
#15 testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>
(object=object@entry=0x8003dd70,
method=(void (testing::Test::*)(testing::Test * const)) 0x4142c8 <NSEBaseMockTest_RetrieveCSE_Test::TestBody()>, this adjustment -2147230352,
location=location@entry=0x484c00 <(anonymous namespace)::b64_decode(std::string const&)::lookup+8000> "the test body") at ./src/gtest.cc:2114
#16 0x0042fb59 in testing::Test::Run (this=0x8003dd70) at ./src/gtest.cc:2151
#17 0x0042fd18 in testing::TestInfo::Run (this=0x8003ac78)
at ./src/gtest.cc:2326
#18 0x0042fe57 in Run (this=<optimized out>) at ./src/gtest.cc:2301
#19 testing::TestCase::Run (this=0x8003b508) at ./src/gtest.cc:2444
#20 0x00430325 in Run (this=<optimized out>) at ./src/gtest.cc:2430
#21 testing::internal::UnitTestImpl::RunAllTests (this=0x8003b330)
at ./src/gtest.cc:4315
#22 0x0044c15c in HandleSehExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool> (
location=0x484d60 <(anonymous namespace)::b64_decode(std::string const&)::lookup+8352> "auxiliary test code (environments or event listeners)",
method=(bool (testing::internal::UnitTestImpl::*)(testing::internal::UnitTestImpl * const)) 0x42ff60 <testing::internal::UnitTestImpl::RunAllTests()>, this adjustment -2147241168, object=0x8003b330) at ./src/gtest.cc:2078
#23 testing::internal::HandleExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool> (object=0x8003b330,
method=(bool (testing::internal::UnitTestImpl::*)(testing::internal::UnitTestImpl * const)) 0x42ff60 <testing::internal::UnitTestImpl::RunAllTests()>, this adjustment -2147241168,
location=location@entry=0x484d60 <(anonymous namespace)::b64_decode(std::string const&)::lookup+8352> "auxiliary test code (environments or event listeners)") at ./src/gtest.cc:2114
#24 0x00430597 in testing::UnitTest::Run (
this=0x4c81c8 <testing::UnitTest::GetInstance()::instance>)
at ./src/gtest.cc:3929
#25 0x0043d793 in RUN_ALL_TESTS ()
at /cygdrive/c/Workspace/gmock-1.7.0/include/gmock/../../../gmock/include/gmock/../../../gmock/include/gmock/internal/../../../../gmock/fused-src/gtest/gtest.h:20058
#26 0x004145c1 in main (argc=1, argv=0x28cc6c) at utest/gmock/gmock_main.cc:60
11 到 #13 似乎增加了对 gmock 内部结构的期望,其中链接列表出现问题。
现在简化为一个源文件以使事情变得清晰。
gmtest.cc
#include "gmock/gmock.h"
#include "gtest/gtest.h"
class Base {
public:
virtual void f1() { };
virtual void f2() { };
};
class BaseMock : public Base {
public:
MOCK_METHOD0(f1, void());
MOCK_METHOD0(f2, void());
};
class BaseMockTest : public ::testing::Test {
};
TEST_F(BaseMockTest, Test1) {
BaseMock bm;
EXPECT_CALL(bm, f1()).Times(1);
std::cout << "EXPECT_CALL done.\n";
}
GTEST_API_ int main(int argc, char** argv) {
std::cout << "Running main() from gmock_main.cc\n";
testing::InitGoogleMock(&argc, argv);
return RUN_ALL_TESTS();
}
并编译链接:
$ g++ -I/mnt/Workspace/gmock/include -I/mnt/Workspace/gmock/gtest/include -g -c gmtest.cc
$ g++ gmtest.o -L/mnt/Workspace/gmock/lib/.libs/ -lgmock -L/mnt/Workspace/gmock/gtest/lib/.libs -lgtest -o gmtest
砰!还是崩溃!任何人都可以验证这一点吗?
射线