[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:
- {
- Q_OBJECT
- private slots:
- void pidsTimerTimeout();
- public:
- QTimer m_PidsTimer;
- };
- void SandboxedAppStat::pidsTimerTimeout()
- {
- qDebug() << "whatever";
- }
- {
- m_PidsTimer.start(500);
- }
- {
- Q_OBJECT
- private:
- static SandboxedAppStat SandboxedAppStat1;
- };
- SandboxedAppStat SandboxedApp::SandboxedAppStat1;
Actually what I’m trying to do, is to simulate static constructor behavior in C++. I want
- m_PidsTimer.start(500);
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 http://dl.dropbox.com/u/3055964/Untitled.gif
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([&] () {
- Sleep(3000);
- t->m_PidsTimer.start(500);
- });
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.
Thanks
5 replies
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 [parashift.com]).
It doesn’t crash with gcc on linux, but it prints the error:
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) {
- t->m_PidsTimer.start(500);}
- , 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?
Thanks
BTW, here’s a simple project consisting of only one header and one source file to reproduce the problem. http://dl.dropbox.com/u/3055964/untitled1.zip
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:
- {
- 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.
You must log in to post a reply. Not a member yet? Register here!
