我的情况是退出软件时偶尔产生这种错误,也算是多线程中的一个使用不当的情况。
简化后的模型如下:

class A
{
public:
    virtual void vf() = 0;
    void fa() {
        vf();
    }
    ~A() {
        fa();
    }
private:
    Thread *thread;
};

class AA : public A
{
    virtual void vf() { /*do something*/ }
};

int main()
{
    AA *aa = new AA;
    delete aa;
    return 0;
}

PureVirtualFuncCall
没错就是在基类的构造/析构函数中对虚函数进行了调用。实际的情况是:线程T1和T2持有同一个AA对象的指针,当T1在对AA进行析构,执行到A::~A()中时,T2还在跑着AA::vf(),因为一旦进入A::~A()后,对象的虚表指针已经被重新指向了基类A的虚表,不再是AA的了,然后在这个间隙里T2产生了对vf()的调用,就抛出异常了。

遇到这个情况,简单的做法是先在AA析构之前先让线程T2终止。然而软件将线程安置在基类中(如上面A::thread),要求派生类去执行停止线程动作,这样便会使得接口的易用性下降,因为很有能会忘记执行了,就跟忘记释放内存一样,在不知不觉中又引回了这个问题。
最后还是去掉了vf的纯虚属性,变成一个实现为空的普通虚函数了。