googletest:测试基类具有纯虚拟方法的派生类时的核心转储
googletest: coredump when testing a derived class whose base class has pure virtual methods
我有一个抽象基类,它具有处理线程生命周期(启动,停止,连接(的逻辑。线程中执行的工作取决于实例化的派生类,并且有多个派生类。
基类如下所示:
class Base {
public:
Base(int i, bool b) : i{i}, b{b}
{
start();
}
virtual bool getB() { return b; };
void stop() { stopWorking = true; workerTh.join(); };
protected:
virtual void start()
{
std::cout << "Base start method" << std::endl;
workerTh = std::thread{ std::bind(&Derived::work, this) };
};
virtual void work() = 0;
std::thread workerTh;
int i;
bool b;
bool stopWorking = false;
};
派生类如下所示:
class Derived : public Base {
public:
Derived(int i, bool b) : Base(i,b) {};
protected:
void work()
{
std::cout << "Derived Work started!" << std::endl;
while (not stopWorking)
{
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
}
std::cout << "Derived Work ended!" << std::endl;
}
};
它在常规程序中按预期运行,例如:
int main()
{
std::cout << "Starting" << std::endl;
Derived d { 10, false};
std::this_thread::sleep_for(std::chrono::milliseconds(2000));
std::cout << "Finishing" << std::endl;
d.stop();
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
}
但是如果我在谷歌测试中执行它,那么我会得到一个核心转储,原因是我正在这一行中调用一个纯虚拟方法:
workerTh = std::thread{ std::bind(&Base::work, this) };
那么,为什么该行在正常程序中按预期工作,但在谷歌测试中崩溃?我在启动GTest时遗漏了什么吗?
这是测试:
#include "BaseDerived.cc"
#include "gtest/gtest.h"
TEST(BaseDerivedWithThreadTest, FailsCoredumpCallingPureVirtual) {
Derived d { 10, false };
ASSERT_FALSE (d.getB());
}
int main(int argc, char **argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
[==========] Running 1 test from 1 test case.
[----------] Global test environment set-up.
[----------] 1 test from BaseDerivedWithThreadTest
[ RUN ] BaseDerivedWithThreadTest.FailsCoredumpCallingPureVirtual
Base start method
terminate called without an active exception
pure virtual method called
terminate called recursively
Aborted (core dumped)
我可以通过将线程生命周期代码归结为派生类来解决此问题,但是我发现它非常丑陋,只是为了让googletest满意。
有什么想法吗?
谢谢!
不幸的是,您的代码已损坏: 在基类构造函数中,您调用start()
,这是虚拟的。这永远不会调用派生类的start()
方法,因为在构造函数中调用时动态类型不属于派生类。这同样适用于虚拟work()
功能。更糟糕的是,根据调度线程的时间,它可能会也可能不会调用派生类的函数,因为到那时,其类型可能已更改为派生类的类型。
测试失败可能只是一个红鲱鱼,你的代码被破坏了。首先修复它,然后查看测试是否仍然失败。
相关文章:
- 分段故障(堆芯转储)矢量
- Cppcheck生成xml转储文件
- 如何找出GDB的SIGTRAP核心转储的根本原因
- C++映射分割错误(核心转储)
- 在c++中初始化矩阵时出现分段错误(核心转储)
- 在c++中键入向量中的所有值后,得到分段错误(核心转储)
- 浮点异常(核心转储)#694457
- 分段错误(核心转储)但无法弄清楚
- 链接到libkcapi时没有核心转储
- 检测到堆栈粉碎:已终止 中止(核心已转储)
- 正在处理故障(堆芯转储)
- 分段错误(核心转储) - 使用 SavedModel 的 Tensorflow C++ API 进行推断
- 我不知道为什么这段代码会让核心被转储?
- C++运行时错误与快速排序算法抛出堆栈转储错误
- 在基数排序中,我得到 munmap_chunk():无效指针和中止(核心转储).为什么?
- C++指针无法在函数外部传递值和分段错误(核心转储)错误
- cygwin_exception::open_stackdumpfile:将堆栈跟踪转储到 class4.exe.sta
- C++快速将 int 数组内容转储到文本文件中
- googletest:测试基类具有纯虚拟方法的派生类时的核心转储
- 转储QObject派生对象的所有属性