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

1class A
2{
3public:
4    virtual void vf() = 0;
5    void fa() {
6        vf();
7    }
8    ~A() {
9        fa();
10    }
11private:
12    Thread *thread;
13};
14 
15class AA : public A
16{
17    virtual void vf() { /*do something*/ }
18};
19 
20int main()
21{
22    AA *aa = new AA;
23    delete aa;
24    return 0;
25}

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

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