title: gmock Segmentationfault on EXPECT_CALL
body: <p>On cygwin, EXPECT_CALL gives segmentation fault. Back trace shows:</p>
  
  <pre><code>Program received signal SIGSEGV, Segmentation fault.
  0x004538e2 in join (ptr=0x61230494 &lt;vtable for pthread_key+12&gt;,
      this=0x8003aedc) at ./gtest/include/gtest/internal/gtest-linked_ptr.h:113
  113         while (p-&gt;next_ != ptr) p = p-&gt;next_;
  (gdb) bt
  #0  0x004538e2 in join (ptr=0x61230494 &lt;vtable for pthread_key+12&gt;,
      this=0x8003aedc) at ./gtest/include/gtest/internal/gtest-linked_ptr.h:113
  #1  copy&lt;testing::internal::ExpectationBase&gt; (
      ptr=0x61230490 &lt;vtable for pthread_key+8&gt;, 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 &lt;vtable for pthread_key+12&gt;
  (gdb) p p
  $2 = (const testing::internal::linked_ptr_internal *) 0x18ec8353
  (gdb) p p-&gt;next_
  Cannot access memory at address 0x18ec8353
  </code></pre>
  
  <p>Looks like some gmock internal link list corruption, but wired because my test is not that complex:</p>
  
  <p>class to mock:</p>
  
  <pre><code>class NSEBase {
  public:
      NSEBase(const std::string&amp; ip, const std::string&amp; port)
          : ip_(ip), port_(port) { } ;
  
      void setRequestHandler(RequestHandler&amp; req_hdl) {
          request_handler_ = &amp;req_hdl;
      };
  
      virtual void send(Response&amp; rsp) { };
      virtual void run() { };
  
      virtual ~NSEBase() { };
  
  private:
      RequestHandler * request_handler_;
      const std::string &amp; ip_, port_;
  };
  </code></pre>
  
  <p>Mock class header:</p>
  
  <pre><code>class NSEBaseMock : public NSEBase {
  public:
    NSEBaseMock(const char* ip, const char* port) : NSEBase(ip, port) {};
    MOCK_METHOD0(run, void());
    MOCK_METHOD1(send, void(Response&amp; rsp));
  };
  </code></pre>
  
  <p>Mock class body:</p>
  
  <pre><code>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&lt;NSEBaseMock&gt;("127.0.0.1", "1234");
          ....  
          // cout shows it got here correctly
      }
  
      virtual void TearDown()
      {
          ....
          delete nse_;
          ....
      }
  
      void handleRequest() {
          req_ = new Request(retrieve_json);
          hdl_-&gt;handleRequest(*req_);
      }
  
  };
  
  const string NSEBaseMockTest::retrieve_json(....);
  
  TEST_F(NSEBaseMockTest, RetrieveCSE) {
  
    EXPECT_CALL(*nse_, run()) **&lt;--- crash here. no matter with .WillOnce or w/o.**
        .WillOnce(Invoke(this, &amp;NSEBaseMockTest::handleRequest));
  
    std::cout &lt;&lt; "EXPECT_CALL() done" &lt;&lt; std::endl;
  
    ON_CALL(*nse_, send(Property(&amp;Response::getResponseStatusCode, Eq(RSC_OK))));
  
    std::cout &lt;&lt; "ON_CALL() done" &lt;&lt; std::endl;
  
  
    server_-&gt;run();
  
  }
  </code></pre>
  
  <p>Search through the gmock forum and here, no clue yet. I'm using all the latest up to today.</p>
  
  <p>Shine me some ideas please:) Thanks.</p>
  
  <p>Ray</p>
  
  <hr>
  
  <p>Sorry Ian for late reply. here is my compile log, same flag for all cc files:</p>
  
  <pre><code>*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*
  </code></pre>
  
  <p>link command:</p>
  
  <pre><code>*`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`*
  </code></pre>
  
  <p>Regarding the ip_, port_ string reference in NSEBase, you are right, but it's not relevant yet, NSEBase is a stub right now, it still crashes.</p>
  
  <p>Complete crash call trace:</p>
  
  <pre><code>Program received signal SIGSEGV, Segmentation fault.
  0x00465002 in join (ptr=0x61230494 &lt;vtable for pthread_key+12&gt;,
      this=0x8003e844) at ./gtest/include/gtest/internal/gtest-linked_ptr.h:113
  113         while (p-&gt;next_ != ptr) p = p-&gt;next_;
  (gdb) bt
  #0  0x00465002 in join (ptr=0x61230494 &lt;vtable for pthread_key+12&gt;,
      this=0x8003e844) at ./gtest/include/gtest/internal/gtest-linked_ptr.h:113
  #1  copy&lt;testing::internal::ExpectationBase&gt; (
      ptr=0x61230490 &lt;vtable for pthread_key+8&gt;, 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=&lt;optimized out&gt;, __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=&lt;optimized out&gt;, __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&lt;testing::Expectation, testing::Expectation, std::_Identity&lt;testing::Expectation&gt;, testing::Expectation::Less, std::allocator&lt;testing::Expectation&gt; &gt;::_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=&lt;optimized out&gt;)
      at /usr/lib/gcc/i686-pc-cygwin/4.9.3/include/c++/bits/stl_set.h:502
  #9  operator+= (e=..., this=&lt;optimized out&gt;)
      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&lt;void ()&gt;::AddNewExpectation(char const*, int, std::string const&amp;, std::tuple&lt;&gt; const&amp;) (
      this=0x8003e188,
      file=0x481bba &lt;testing::_+104&gt; "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&lt;void ()&gt;::InternalExpectedAt(char const*, int, char const*, char const*) (this=0x8003e1ac,
      file=0x481bba &lt;testing::_+104&gt; "utest/gmock/NSEBase_mock.cc", line=74,
      obj=0x481bb4 &lt;testing::_+98&gt; "*nse_",
      call=0x481bae &lt;testing::_+92&gt; "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&lt;testing::Test, void&gt; (
      location=0x484c00 &lt;(anonymous namespace)::b64_decode(std::string const&amp;)::lookup+8000&gt; "the test body",
      method=&amp;virtual table offset 16, this adjustment -2147230352,
  ---Type &lt;return&gt; to continue, or q &lt;return&gt; to quit---
      object=0x8003dd70) at ./src/gtest.cc:2078
  #15 testing::internal::HandleExceptionsInMethodIfSupported&lt;testing::Test, void&gt;
      (object=object@entry=0x8003dd70,
      method=(void (testing::Test::*)(testing::Test * const)) 0x4142c8 &lt;NSEBaseMockTest_RetrieveCSE_Test::TestBody()&gt;, this adjustment -2147230352,
      location=location@entry=0x484c00 &lt;(anonymous namespace)::b64_decode(std::string const&amp;)::lookup+8000&gt; "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=&lt;optimized out&gt;) at ./src/gtest.cc:2301
  #19 testing::TestCase::Run (this=0x8003b508) at ./src/gtest.cc:2444
  #20 0x00430325 in Run (this=&lt;optimized out&gt;) at ./src/gtest.cc:2430
  #21 testing::internal::UnitTestImpl::RunAllTests (this=0x8003b330)
      at ./src/gtest.cc:4315
  #22 0x0044c15c in HandleSehExceptionsInMethodIfSupported&lt;testing::internal::UnitTestImpl, bool&gt; (
      location=0x484d60 &lt;(anonymous namespace)::b64_decode(std::string const&amp;)::lookup+8352&gt; "auxiliary test code (environments or event listeners)",
      method=(bool (testing::internal::UnitTestImpl::*)(testing::internal::UnitTestImpl * const)) 0x42ff60 &lt;testing::internal::UnitTestImpl::RunAllTests()&gt;, this adjustment -2147241168, object=0x8003b330) at ./src/gtest.cc:2078
  #23 testing::internal::HandleExceptionsInMethodIfSupported&lt;testing::internal::UnitTestImpl, bool&gt; (object=0x8003b330,
      method=(bool (testing::internal::UnitTestImpl::*)(testing::internal::UnitTestImpl * const)) 0x42ff60 &lt;testing::internal::UnitTestImpl::RunAllTests()&gt;, this adjustment -2147241168,
      location=location@entry=0x484d60 &lt;(anonymous namespace)::b64_decode(std::string const&amp;)::lookup+8352&gt; "auxiliary test code (environments or event listeners)") at ./src/gtest.cc:2114
  #24 0x00430597 in testing::UnitTest::Run (
      this=0x4c81c8 &lt;testing::UnitTest::GetInstance()::instance&gt;)
      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
  </code></pre>
  
  <h1>11 to #13 seems to add expectation to gmock internal structure, where link list got trouble.</h1>
  
  <hr>
  
  <p>Now simplify into one source file to make things clear.</p>
  
  <p>gmtest.cc</p>
  
  <pre><code>#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 &lt;&lt; "EXPECT_CALL done.\n";
  }
  
  GTEST_API_ int main(int argc, char** argv) {
    std::cout &lt;&lt; "Running main() from gmock_main.cc\n";
    testing::InitGoogleMock(&amp;argc, argv);
    return RUN_ALL_TESTS();
  }
  </code></pre>
  
  <p>And compile link:</p>
  
  <pre><code>$ 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
  </code></pre>
  
  <p>Bom! Still crash!
  Can anybody verify this? </p>
  
  <p>Ray</p>