64-bit Qt for windows: QtScript crashes.
Hello.
I have compiled Qt for 64-bit architecture under windows and all works fine except QtScript. The following simple code, working perfectly with 32-bit Qt for windows installed from qtsoftware.com, crashes if compiled with 64-bit Qt :(. Maybe it's an error in my code? Or Qt is not compatible with 64-bit? Or it is a bug and i need to submit it somehow?
Qt console project.
main.h
Code:
#pragma once
#include <QObject>
#include <QScriptEngine>
{
Q_OBJECT;
public slots: void Test();
private: QScriptEngine m_oEngine;
};
{
Q_OBJECT;
signals: void ScriptTest();
};
main.cpp
Code:
#include <QtCore/QCoreApplication>
#include <QThread>
#include "main.h"
void Script::Test()
{
QString sScript
= "function OnStart() { var a = [ [ 0 ] ]; " "for( var i = 0; i < 3; i ++ ) { for( var j = 0; j < 100; j ++ ) "
"{ \"a\" + a[ 0 ][ 0 ]; } } }";
m_oEngine.evaluate( sScript );
QScriptValue oFnStart = m_oEngine.evaluate( "OnStart" );
oFnStart.call();
}
int main(int argc, char *argv[])
{
scriptThread.start();
Script script;
script.moveToThread( & scriptThread );
App app;
script.connect( & app, SIGNAL( ScriptTest() ), SLOT( Test() ) );
app.startTimer( 50 );
return a.exec();
}
Re: 64-bit Qt for windows: QtScript crashes.
Where does it crash exactly?
Re: 64-bit Qt for windows: QtScript crashes.
Inside QtScript internals. Call stack:
0 QtScriptd4!QTJSC::JSValue::get jsobject.h 641 0x1800b313a
1 QtScriptd4!QTJSC::JSValue::get jsobject.h 628 0x1800b304d
2 QtScriptd4!QTJSC::Interpreter::privateExecute interpreter.cpp 2539 0x1800a6c7e
3 QtScriptd4!QTJSC::Interpreter::execute interpreter.cpp 753 0x18009fa53
4 QtScriptd4!QTJSC::JSFunction::call jsfunction.cpp 120 0x1801018ad
5 QtScriptd4!QTJSC::call calldata.cpp 62 0x1800c7d06
6 QtScriptd4!QScriptValue::call qscriptvalue.cpp 1880 0x1801b9636
7 qt_script_test!Script::Test main.cpp 12 0x14000126d
8 qt_script_test!Script::qt_metacall moc_main.cpp 75 0x1400019d3
9 QtCored4!QMetaObject::metacall qmetaobject.cpp 238 0x672219c1
10 QtCored4!QMetaCallEvent::placeMetaCall qobject.cpp 575 0x6723643c
11 QtCored4!QObject::event qobject.cpp 1252 0x672378ad
12 QtCored4!QCoreApplicationPrivate::notify_helper qcoreapplication.cpp 840 0x67216cc6
13 QtCored4!QCoreApplication::notify qcoreapplication.cpp 785 0x67216a49
14 QtCored4!QCoreApplication::notifyInternal qcoreapplication.cpp 704 0x6721693a
15 QtCored4!QCoreApplication::sendEvent qcoreapplication.h 215 0x6721cd20
16 QtCored4!QCoreApplicationPrivate::sendPostedEvents qcoreapplication.cpp 1345 0x67217d7e
17 QtCored4!qt_internal_proc qeventdispatcher_win.cpp 509 0x67264eda
18 USER32!GetSystemMetrics USER32 0 0x771bc3c1
19 USER32!GetSystemMetrics USER32 0 0x771bc60a
20 QtCored4!QEventDispatcherWin32::processEvents qeventdispatcher_win.cpp 753 0x6726603f
21 QtCored4!QEventLoop::processEvents qeventloop.cpp 150 0x67213d6a
22 QtCored4!QEventLoop::exec qeventloop.cpp 201 0x67213ef1
23 QtCored4!QThread::exec qthread.cpp 487 0x6706e2c5
24 QtCored4!QThread::run qthread.cpp 547 0x6706e403
25 QtCored4!QThreadPrivate::start qthread_win.cpp 315 0x67072d87
26 MSVCR90D!beginthreadex MSVCR90D 0 0x73754ee5
27 MSVCR90D!beginthreadex MSVCR90D 0 0x73754ead
28 kernel32!BaseThreadInitThunk kernel32 0 0x772bf56d
29 ntdll!RtlUserThreadStart ntdll 0 0x773f3281
I have submitted a bug (http://bugreports.qt.nokia.com/browse/QTBUG-7433) but i'm still unsure is it a Qt bug or i'm doing something wrong -_-.
Re: 64-bit Qt for windows: QtScript crashes.
QScriptEngine lives in the main thread where it was created and is called by the second thread where script lives. QScriptEngine is not thread-safe so this is bad.
moveToThread also moves child objects so you could make the script engine a child of the Script object and they would hapily live in the same thread. Something like:
Code:
{
Q_OBJECT;
public: Script() : m_oEngine(this) {}
public slots: void Test();
private: QScriptEngine m_oEngine;
};
Re: 64-bit Qt for windows: QtScript crashes.
I have already checked this. Removing moveToThread() from code changes nothing - same crash in same place :(
Re: 64-bit Qt for windows: QtScript crashes.
Just to be certain, modify your code this way:
Code:
Q_OBJECT
public:
MyThread
() : QThread() { m_interpreter
= 0;
} void run() {
m_interpreter = new QScriptEngine(this);
exec();
delete m_interpreter;
m_interpreter = 0;
}
public slots:
void test() {
if(!m_interpreter) return;
m_interpreter->evaluate(...);
}
private:
QScriptEngine *m_interpreter;
};
Then connect appropriate signals, etc.
Re: 64-bit Qt for windows: QtScript crashes.
I have modified the code following way:
main.h
Code:
#pragma once
#include <QObject>
#include <QScriptEngine>
#include <QThread>
Q_OBJECT
public:
MyThread
() : QThread() { m_interpreter
= 0;
} void run();
public slots:
void test();
private:
QScriptEngine *m_interpreter;
};
{
Q_OBJECT;
signals: void ScriptTest();
};
main.cpp
Code:
#include <QtCore/QCoreApplication>
#include <QThread>
#include "main.h"
void MyThread::run()
{
m_interpreter = new QScriptEngine(this);
exec();
delete m_interpreter;
m_interpreter = 0;
}
void MyThread::test()
{
if(!m_interpreter) return;
QString sScript
= "function OnStart() { var a = [ [ 0 ] ]; " "for( var i = 0; i < 3; i ++ ) { for( var j = 0; j < 100; j ++ ) "
"{ \"a\" + a[ 0 ][ 0 ]; } } }";
m_interpreter->evaluate( sScript );
}
int main(int argc, char *argv[])
{
MyThread oThread;
oThread.start();
App app;
QObject::connect( & app,
SIGNAL( ScriptTest
() ),
& oThread,
SLOT( test
() ) );
app.startTimer( 50 );
return a.exec();
}
It shows following debug information at runtime:
QObject: Cannot create children for a parent that is in a different thread.
(Parent is MyThread(0x12fe60), parent's thread is QThread(0x1b98960), current th
read is MyThread(0x12fe60)
At string:
Code:
m_interpreter = new QScriptEngine(this);
It seems i have modified something wrong?
Re: 64-bit Qt for windows: QtScript crashes.
You forgot to move the thread to its own thread.
Re: 64-bit Qt for windows: QtScript crashes.
Quote:
You forgot to move the thread to its own thread.
OMG. I was sure that QThread::run() will know what thread it is O_O. This is very strange design :).
Anyway, i have started code and... it did not crash O_O. The only thing i can suggest is that QScriptEngine somehow remembers a thread it was CREATED in and ignores moveToThread() after it is created. I will perform more deep tests to ensure that all is correct. Lots of thanks to you. It's really good to have a guru status in some technology - you can use magic :).
Re: 64-bit Qt for windows: QtScript crashes.
Ah, no :(
It seems your test code missed
Code:
QScriptValue oFnStart = m_oEngine.evaluate( "OnStart" );
oFnStart.call();
After this is added, code start crashing again in same place :(.
Re: 64-bit Qt for windows: QtScript crashes.
Quote:
Originally Posted by
eyeofhell
OMG. I was sure that QThread::run() will know what thread it is O_O. This is very strange design :).
Anyway, i have started code and... it did not crash O_O. The only thing i can suggest is that QScriptEngine somehow remembers a thread it was CREATED in and ignores moveToThread() after it is created. I will perform more deep tests to ensure that all is correct. Lots of thanks to you. It's really good to have a guru status in some technology - you can use magic :).
OMG. I don't know how many times it has to be repeated... Only the body of run() method is in newly created thread, so everything created outside of this method is still in old thread...:
Code:
MyTread mt;
mt.start(); // <--- this creates new thread!
// mt object is still in old thread
// so everything cerated in its constructor also
And this is nothing new. Did you ever looked at Qt Examples & Demos and their documentation (like threaded fortune server?)
Re: 64-bit Qt for windows: QtScript crashes.
Quote:
OMG. I don't know how many times it has to be repeated... Only the body of run() method is in newly created thread, so everything created outside of this method is still in old thread...:
As you can see in the code, engine is created exactly in run() method. I was a little dissapointed that QThread object itself is counted to be in the different thread than it's own run() method :). It's a QThread after all.
Anyway, the QtScriptEngine still crashes by reasons unknown - and that's the main problem. And it crashes regardless of what thread it is in :(.
Re: 64-bit Qt for windows: QtScript crashes.
There is no "oFnStart" object in our test program. Could you add it there and post the code again? Please include the code of the evaluated script and the result of QScriptValue::isFunction().
By the way, to correct what has been said earlier:
Code:
public:
// ...
private:
QScriptEngine engine;
};
Running
Code:
Object *o = new Object;
o->moveToThread(...);
will not move the "engine" object to the target thread. "engine" is a member and not a child of the "o" object.
Re: 64-bit Qt for windows: QtScript crashes.
Quote:
Originally Posted by
eyeofhell
As you can see in the code, engine is created exactly in run() method. I was a little dissapointed that QThread object itself is counted to be in the different thread than it's own run() method :). It's a QThread after all.
Read again what faldżip has written. He means exactly that - how can an object (QThread instance) created before the thread is spawned be handled by that thread? What do you think the following should do:
Code:
Q_OBJECT
public:
Thread() ...
public slots:
void callMe(){ ... }
};
//...
Thread thread;
In context of which thread would it execute? Note there is no call to QThread::start() anywhere in the code.
And then where would this execute?
Code:
Thread thread;
thread.start();
thread.wait(); // hangs until thread is finished
QThread doesn't represent the thread... it is a controller of the thread.
Re: 64-bit Qt for windows: QtScript crashes.
Quote:
There is no "oFnStart" object in our test program. Could you add it there and post the code again?
Complete code of latest test, based on your proposals. main.cpp:
Code:
#include <QtCore/QCoreApplication>
#include <QThread>
#include "main.h"
void MyThread::run()
{
m_interpreter = new QScriptEngine(this);
exec();
delete m_interpreter;
m_interpreter = 0;
}
void MyThread::test()
{
if(!m_interpreter) return;
QString sScript
= "function OnStart() { var a = [ [ 0 ] ]; " "for( var i = 0; i < 3; i ++ ) { for( var j = 0; j < 100; j ++ ) "
"{ \"a\" + a[ 0 ][ 0 ]; } } }";
m_interpreter->evaluate( sScript );
QScriptValue oFnStart = m_interpreter->evaluate( "OnStart" );
Q_ASSERT( oFnStart.isFunction() );
oFnStart.call();
}
int main(int argc, char *argv[])
{
MyThread oThread;
oThread.moveToThread( & oThread );
oThread.start();
App app;
QObject::connect( & app,
SIGNAL( ScriptTest
() ),
& oThread,
SLOT( test
() ) );
app.startTimer( 50 );
return a.exec();
}
main.h
Code:
#pragma once
#include <QObject>
#include <QScriptEngine>
#include <QThread>
Q_OBJECT
public:
MyThread
() : QThread() { m_interpreter
= 0;
} void run();
public slots:
void test();
private:
QScriptEngine *m_interpreter;
};
{
Q_OBJECT;
signals: void ScriptTest();
};
Quote:
Please include the code of the evaluated script
Do you means the text inside evaluate call()? It's in code:
Code:
QString sScript
= "function OnStart() { var a = [ [ 0 ] ]; " "for( var i = 0; i < 3; i ++ ) { for( var j = 0; j < 100; j ++ ) "
"{ \"a\" + a[ 0 ][ 0 ]; } } }";
m_interpreter->evaluate( sScript );
Quote:
and the result of QScriptValue::isFunction().
It's always true, assert never trigger:
Code:
Q_ASSERT( oFnStart.isFunction() );
Re: 64-bit Qt for windows: QtScript crashes.
If it crashes on call() then you have to first verify your function is correct. I suggest adding some debug statements inside. If evaluate() returns then it seems the engine itself works correctly.
Re: 64-bit Qt for windows: QtScript crashes.
Quote:
If it crashes on call() then you have to first verify your function is correct
Function is included in code. It's extremly simple. And i was sure that QtScript interpreter is stable and will not crash on wrong script code. Is it not stable?
Re: 64-bit Qt for windows: QtScript crashes.
Don't ask me, verify it. There is probably some race condition there that is causing the crash. It is important to know where exactly it crashes.
Re: 64-bit Qt for windows: QtScript crashes.
I have successfully shrinked down the code to following minimum. No threads at all, no race conditions. Still crashes at call():
Code:
#include <QtCore/QCoreApplication>
#include <QScriptEngine>
int main(int argc, char *argv[])
{
QScriptEngine oEngine;
QString sScript
= "function OnStart() { var a = [ [ 0 ] ]; " "for( var i = 0; i < 3; i ++ ) { for( var j = 0; j < 100; j ++ ) "
"{ \"a\" + a[ 0 ][ 0 ]; } } }";
oEngine.evaluate( sScript );
for(;;)
{
QScriptValue oFnStart = oEngine.evaluate( "OnStart" );
Q_ASSERT( oFnStart.isFunction() );
oFnStart.call();
}
}
Re: 64-bit Qt for windows: QtScript crashes.
Why don't you just do what I said and debug the ecma script code?