QMetaObject::invokeMethod() occasionally results in pure virtual error/crash



  • We are having trouble tracking down the cause of a crash.
    Occasionally our program is crashing with the error:
    pure virtual method called
    terminate called without an active exception
    Aborted

    Configuration:
    Qt 4.8.2 on SUSE Enterprise Linux

    Here is a simple example of our code:
    @
    class someObj : public QObject
    {
    Q_OBJECT
    public:
    void openObj(){
    QMetaObject::invokeMethod(this, "openObjImpl");
    }
    private slots:
    void openObjImpl(){
    doStuff();
    }
    void doStuff() {/.../}
    signals:
    void readyClose();
    };

    class controller : public QObject
    {
    Q_OBJECT
    public:
    void createObj();
    void open();

    private:
    QThread *thread;
    SomeObj *someObj;
    };

    void controller::createObj()
    {
    thread = new QThread;
    someObj = new SomeObj;
    someObj->moveToThread(active.thread);
    thread->start();
    }

    void controller::open()
    {
    createObj();
    someObj->openObj();
    }

    /.../

    controller cc = new controller;
    /
    .../
    cc.open();
    /
    ...*/
    @

    This crash does not happen often, most of the time it will run several hours, sometimes it runs a few days before it crashes.
    The controller->open() function gets called once every 5 seconds. (closing and deleting thread and someObj omitted for brevity).

    Top of the stacktrace for this crash shows:
    @
    Thread 1 (Thread 0x7ffff7f89780 (LWP 9979)):
    #0 0x00007fffeb6f8b55 in raise () from /lib64/libc.so.6
    #1 0x00007fffeb6fa131 in abort () from /lib64/libc.so.6
    #2 0x00007fffebf87e4d in __gnu_cxx::__verbose_terminate_handler() ()
    from /usr/lib64/libstdc++.so.6
    #3 0x00007fffebf85ff6 in ?? () from /usr/lib64/libstdc++.so.6
    #4 0x00007fffebf86023 in std::terminate() () from /usr/lib64/libstdc++.so.6
    #5 0x00007fffebf86a3f in __cxa_pure_virtual () from /usr/lib64/libstdc++.so.6
    #6 0x00007fffec7ff4d6 in QCoreApplication::postEvent(QObject*, QEvent*, int)
    () from /opt/lib/libQtCore.so.4
    #7 0x00007fffec8049cb in QMetaMethod::invoke(QObject*, Qt::ConnectionType, QGenericReturnArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgum
    ent, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument) const ()
    from /opt/lib/libQtCore.so.4
    #8 0x00007fffec80607e in QMetaObject::invokeMethod(QObject*, char const*, Qt::ConnectionType, QGenericReturnArgument, QGenericArgument, QGenericArgument, QGenericArgu
    ment, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument) ()
    from /opt/lib/libQtCore.so.4
    #9 0x00000000004a3597 in QMetaObject::invokeMethod (obj=0x5d44d50, member=
    0x587a3b "openObjImpl", type=Qt::QueuedConnection, val0=..., val1=..., val2=
    ..., val3=..., val4=..., val5=..., val6=..., val7=..., val8=..., val9=...)
    at /opt/include/QtCore/qobjectdefs.h:418
    #10 0x000000000052e8c7 in someObj::openObj (this=0x5d44d50, url=
    ..., contextId=3) at someObj.cpp:76
    #11 0x00000000005090b4 in controller::open (this=0x1b78580, contextId=3,
    controlUrl=...) at controller.cpp:386
    #12 0x0000000000539e1f in someManager::openContext (this=0x1ab5860, contextId=
    3, paneId=8) at someManager.cpp:408
    #13 0x00000000005780ae in someManager::qt_static_metacall (_o=0x1ab5860, _c=
    QMetaObject::InvokeMetaMethod, _id=3, _a=0x7fffc1011ad0)
    at moc_someManager.cpp:101
    #14 0x00007fffec80d3b6 in QObject::event(QEvent*) ()
    from /opt/lib/libQtCore.so.4
    #15 0x0000000000536dbe in someManager::event (this=0x1ab5860, ev=
    0x7fffc07520d0) at someManager.cpp:590
    #16 0x00007fffed08abdd in QApplicationPrivate::notify_helper(QObject*, QEvent*)
    () from /opt/lib/libQtGui.so.4
    @

    It appears this line is responsible:
    @
    QMetaObject::invokeMethod(this, "openObjImpl");
    @

    I have considered the possibility that a virtual function is getting called in constructor or destructor or from a separate thread while object is getting constructed or destructed, but the openObj is only called after the object is fully constructed, and none of the functions we implemented are virtual. The openObj() function is always called from the main thread.

    Most of the time everything works fine, and we don't have a reliable way to reproduce, running it overnight usually results in this crash though.
    I am running out of ideas for this one...Could there be a problem with the QThread, or it was not able to move it someObj properly or fully? Could constantly creating and destroying threads cause a problem?


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.