在 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 解决了。
我是 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 解决了。