在 Google Mock 中双倍免费

Double free in Google Mock

我是 Google 测试和模拟框架的新手。

我只是尝试运行"Turtle"例子,成功了。

但是,显示了错误消息:双重释放或损坏 (!prev)。

MockTurtle.h

#include <gmock/gmock.h>

class MockTurtle : class Turtle {
    MOCK_METHOD0(PenUp, void());
    MOCK_METHOD0(PenDown, void());
    MOCK_METHOD1(Forward, void(int distance));
    MOCK_METHOD1(Turn, void(int degrees));
    MOCK_METHOD2(GoTo, void(int x, int y));
    MOCK_CONST_METHOD0(GetX, int());
    MOCK_CONST_METHOD0(GetY, int());
};    

Turtle.h

class Turtle {
    virtual ~Turtle() {}
    virtual void PenUp() = 0;
    virtual void PenDown() = 0;
    virtual void Forward(int distance) = 0;
    virtual void Turn(int degrees) = 0;
    virtual void GoTo(int x, int y) = 0;
    virtual int GetX() const = 0;
    virtual int GetY() const = 0;
};    

Painter.h

class Painter    
{
       Turtle* turtle;
public:
       Painter( Turtle* turtle )
               :       turtle(turtle){}

       bool DrawCircle(int, int, int){
               turtle->PenDown();
               return true;
       }
};    

Main_test.cpp

#include <gtest/gtest.h>
#include <gmock/gmock.h>
#include "Painter.h"
#include "MockTurtle.h"

using ::testing::AtLeast;

TEST(PainterTest, CanDrawSomething) {
 MockTurtle turtle;
 EXPECT_CALL(turtle, PenDown())
     .Times(AtLeast(1));

 Painter painter(&turtle);

 EXPECT_TRUE(painter.DrawCircle(0, 0, 10));
}

int main(int argc, char** argv) {
 // The following line must be executed to initialize Google Mock
 // (and Google Test) before running the tests.
 ::testing::InitGoogleMock(&argc, argv);
 return RUN_ALL_TESTS();
}    

结果

[==========] Running 1 test from 1 test case.    
[----------] Global test environment set-up.
[----------] 1 test from PainterTest
[ RUN      ] PainterTest.CanDrawSomething
[       OK ] PainterTest.CanDrawSomething (0 ms)
[----------] 1 test from PainterTest (0 ms total)
[----------] Global test environment tear-down
[==========] 1 test from 1 test case ran. (1 ms total)
[  PASSED  ] 1 test.
*** Error in `/home/user/workspace/google_mock_2/Debug/google_mock_2': double free or corruption (!prev): 0x098a8080 ***

我尝试 google,发现了几个相同的问题。人们说不应该使用模拟作为全局变量。

但是我的例子没有使用全局变量

请帮我解释一下为什么会出现double free。 提前致谢!

您的错误出在您没有向我们展示的地方。我设法添加了足够的 headers 和定义来编译您的示例:

#include <gtest/gtest.h>
#include <gmock/gmock.h>

class Turtle {
public:
    virtual ~Turtle() = default;
    virtual void PenDown() = 0;
};

class MockTurtle : public Turtle {
public:
    MOCK_METHOD0(PenDown, void());
};


class Painter
{
    Turtle *turtle;

public:
    Painter(Turtle *turtle)
        : turtle(turtle)
    {}

    bool DrawCircle(int, int, int)
    {
        turtle->PenDown();
        return true;
    }
};

TEST(PainterTest, CanDrawSomething)
{
    MockTurtle turtle;
    EXPECT_CALL(turtle, PenDown()).Times(testing::AtLeast(1));

    Painter painter(&turtle);
    EXPECT_TRUE(painter.DrawCircle(0, 0, 10));
}

使用此生成文件:

VPATH += $(GTEST_DIR)/src
VPATH += $(GMOCK_DIR)/src
gtest%.o: CPPFLAGS += -I$(GTEST_DIR)
gmock%.o: CPPFLAGS += -I$(GMOCK_DIR)

40762798: CXXFLAGS += -isystem $(GTEST_DIR)/include -isystem $(GMOCK_DIR)
40762798: CXXFLAGS += -pthread -Wno-effc++
40762798: LDLIBS += -lpthread
40762798: CC=g++
40762798: 40762798.o gtest_main.o gtest-all.o gmock-all.o

然后我就没有错误了,Valgrind 给出了一个干净的健康证明:

valgrind  ./40762798 
==24351== Memcheck, a memory error detector
==24351== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==24351== Using Valgrind-3.12.0.SVN and LibVEX; rerun with -h for copyright info
==24351== Command: ./40762798
==24351== 
Running main() from gtest_main.cc
[==========] Running 1 test from 1 test case.
[----------] Global test environment set-up.
[----------] 1 test from PainterTest
[ RUN      ] PainterTest.CanDrawSomething
[       OK ] PainterTest.CanDrawSomething (84 ms)
[----------] 1 test from PainterTest (92 ms total)

[----------] Global test environment tear-down
[==========] 1 test from 1 test case ran. (125 ms total)
[  PASSED  ] 1 test.
==24351== 
==24351== HEAP SUMMARY:
==24351==     in use at exit: 0 bytes in 0 blocks
==24351==   total heap usage: 183 allocs, 183 frees, 117,387 bytes allocated
==24351== 
==24351== All heap blocks were freed -- no leaks are possible
==24351== 
==24351== For counts of detected and suppressed errors, rerun with: -v
==24351== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

上次,我在 SHARED 库中构建了 google 测试和 google 模拟。 并且发生了错误(双重释放)。

我尝试构建为 STATIC 库。此错误不再出现。 我不知道为什么,但我会调查以了解更多详细信息。

我遇到了同样的问题。在我的例子中,问题是链接 google 测试和 google 模拟。我通过链接 gmock 解决了这个问题,没有 gtest。

我认为发生这种情况是因为据我了解,gmock 已经静态链接 gtest:当您将 gmock 编译为动态库时,也会在 gmock 所在的同一文件夹中生成 gtest(作为静态库)建成。我想 gmock 依赖并使用这个库。

我想,以某种方式,链接 gtest 两次(静态和动态),会产生要执行两次的 free()。

请注意,这是 gtest/gmock 中用于 CMake 共享库构建的错误。它已经用 this pull request. For more details read the discussion in issue 930 解决了。