2015-07-26 3 views
1

В cygwin EXPECT_CALL дает ошибку сегментации. Назад след показывает:gmock Segmentationfault на 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_; 
}; 

заголовок Mock класс:

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)); 
}; 

Mock класс корпус:

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 и здесь, еще нет подсказки. Я использую все последние до сегодняшнего дня.

Покажите мне несколько идей :) Спасибо.

Ray


К сожалению Ian для последнего ответа. вот мой лог компиляции, то же флаг для все куб.см файлов: команда

*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`* 

Что касается IP_, port_ ссылки строки в NSEBase, вы правы, но это не имеет значения еще, 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> 
    ([email protected]=0x8003dd70, 
    method=(void (testing::Test::*)(testing::Test * const)) 0x4142c8 <NSEBaseMockTest_RetrieveCSE_Test::TestBody()>, this adjustment -2147230352, 
    [email protected]=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, 
    [email protected]=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 

Bom! Все еще крушение! Можно ли это проверить?

Ray

+0

Аварии в gmock часто таинственны ... Пара вопросов: (1) как вы компилируете и связываете символы gmock? Если вы не используете согласованные параметры компилятора, часто возникают непредвиденные сбои. Кроме того, не уверен, что это связано, но в NSEBase вы сохраняете жесткие ссылки на std :: string, но при конструировании NSEBaseMock вы передаете временные значения. Это означает, что ссылки на ip_ и port_ не будут действительны после возврата конструктора. – Ian

+0

Несколько вещей: (1) вам нужно посмотреть флаги компилятора, используемые для компиляции источников * gmock *, а также ваших собственных источников. Для этого они должны быть совместимы. (2) если это * является * проблемой флагов компилятора, то, вероятно, наиболее вероятным кандидатом является -std = gnu ++ 11. Если библиотека gmock, в которой ваша ссылка не была скомпилирована с -std = gnu ++ 11, то все ставки отключены с точки зрения совместимости. – Ian

+0

Некоторые обновления. Такой же код работает на Ubuntu. Я перекомпилировал gmock и gtest внутри него с помощью -std = gnu ++ 11 на cygwin, к сожалению, то же самое - сбой. Нужно найти альтернативы. –

ответ

2

Получил решение. Возможно, Ян прав, все еще компилируйте проблему несогласованности флагов между моим кодом и Gmock. Поэтому используйте исходный код fm gmock вместо libs, и проблема исчезла. Сформировать плавленый код gmock:

scripts/python fuse_gmock_files.py OUTPUT_DIR 

и вытащить его в свой проект, то не забудьте изменить настройки, чтобы удалить gmock/GTEST LIBS сборки.

0

У меня такие же проблемы, и действительно, это были несовместимые флаги компилятора. У меня есть cmake 2.8/CentOS 6.8, который мне нужно скомпилировать под cmake 3.6/Cygwin 2.9 для исполнения Windows 10. Я собрал как gtest, так и мой проект с включенным VERBOSE и сравнил используемые флаги. Затем я добавил add_definitions(-DGTEST_HAS_PTHREAD=1) в мой проект cmake и не имею проблем с моими модульными тестами, которые используют gtest & gmock.

Смежные вопросы