Important: Please read the Qt Code of Conduct -

[Solved] crash. QObject::connect in a constructor of a static object instance.

  • I'm trying to find out why my app crashes for the whole day. A picture worth thousands of words, so take a look at this code:

    @class SandboxedAppStat : public QObject

    private slots:
    void pidsTimerTimeout();

    QTimer m_PidsTimer;

    SandboxedAppStat(QObject *parent = NULL);


    void SandboxedAppStat::pidsTimerTimeout()
    qDebug() << "whatever";

    SandboxedAppStat::SandboxedAppStat(QObject *parent)
    : QObject(parent)
    bool b = QObject::connect(&m_PidsTimer), SIGNAL(timeout()), this, SLOT(pidsTimerTimeout()));

    @class SandboxedApp : public QObject

    static SandboxedAppStat SandboxedAppStat1;

    SandboxedAppStat SandboxedApp::SandboxedAppStat1;

    Actually what I'm trying to do, is to simulate static constructor behavior in C++. I want
    @QObject::connect(&m_PidsTimer), SIGNAL(timeout()), this, SLOT(pidsTimerTimeout()));

    to be called as soon as the static member SandboxedAppStat1 initializes. That's why the code shown above is in the constructor of SandboxedAppStat.
    However, my problem is that when I run the program, it crashes as soon as it reaches the line @connect(&m_PidsTimer), SIGNAL(timeout()), this, SLOT(pidsTimerTimeout()));@

    with error code c0000005 (access violation I guess).
    here's the screenshot

    If I declare SandboxedAppStat as a non static variable, then there is no crash and no errors. everything works fine.
    First I thought that crash reason could be the fact that, static members are initialized too early for QObject::connect to be able to be called, that's why I updated SandboxedAppStat constructor with the following code:

    @ auto *t = this;
    QtConcurrent::run([&] () {
    bool b = QObject::connect(&(t->m_PidsTimer), SIGNAL(timeout()), t, SLOT(pidsTimerTimeout()));

    As you can see, QObject::connect executes after 3 seconds when static SanboxedAppStat is initialized, but this didn't help either, the program crashes after 3 seconds.
    I'm really confused, I don't understand what can be the cause of this problem. Can't we use signal/slots in a static object instances?

    I'm using Qt 4.8.0 with MSVC 2010.


  • For the first method, the problem might be that the metaobject needed for connecting the slot is not yet initialized (See "the static order initialization fiasco in the C++ FAQ":

    It doesn't crash with gcc on linux, but it prints the error:
    @QObject::startTimer: QTimer can only be used with threads started with QThread@

    And for the second method, with the lambda, I think the crash is caused by the variable t going out of scope, and not pointing to a valid pointer at the time the connect call occurs. You could pass it as a binded parameter to run:

    @QtConcurrent::run([&] (decltype(this) t) {
    bool b = QObject::connect(&(t->m_PidsTimer), SIGNAL(timeout()), t, SLOT(pidsTimerTimeout()));
    , this);

  • @alexisdm thank you for your answer. You were right about the lambdas, I followed your suggestion and didn't had a crash after that.
    However, about static order initialization, as far as I'm aware, this can occur only if a static object/function tries to access another static object in different compilation unit. Does this mean that Qt meta object stuff is accessing my static member from a static function? And if so, why? what's the reason behind this?


  • BTW, here's a simple project consisting of only one header and one source file to reproduce the problem.

  • The static data being accessed is the meta information generated by the moc for your SandboxedAppStat class, in the file moc_yourfilename.cpp.

    You could try printing the class name to confirm the problem:
    @SandboxedAppStat::SandboxedAppStat(QObject *parent)
    : QObject(parent)
    std::cout << Q_FUNC_INFO << std::endl; // just to confirm we entered the function
    std::cout << "class name: " << SandboxedAppStat::staticMetaObject.className() << std::endl;
    I tested and it does crash with msvc2010, but works fine with gcc.

  • @alexisdm thank you very much, your post saved me :)

Log in to reply