Segmentation fault when calling setContextProperty
-
Hi All,
I am developing a Qt hmi project and below mentioned is the design that I am following for view part.
-
Each QML file has a C++ class for interaction with other layers in my project. And, of course these C++ classes are inherited from QObject.
for example: "A.qml" has a corresponding class "ClassA" that is inherited from QObject -
An other class "ClassViewLoader" is responsible for
a. loading and unloading qml files.
b. creation and deletion of corresponding C++ classes.
"ClassViewLoader" stores the list of instances loaded qmls and corresponding C++ objects.
Code snippets :
A.qml :
Rectangle{ id: mainwindow width: 300; height: 400; color : "black" Connections{ target: instanceofClassA onSomeSignal: { console.log("Received some signal"); } } }
Corresponding C++ class is :
class ClassA :public QObject { Q_OBJECT signals: void someSignal(); public: explicit ClassA (QObject *parent = 0); ~ClassA (); };
View loader class is :
struct Q_COMPONENT{ //pitsCQObjectBase is pointer to view class that owns a QML (for example ClassA) QObject * pitsCQObjectBase; QQmlComponent * pitsQmlComponent; QObject * pitsQmlObject; }; struct LOADED_VIEWS{ Q_COMPONENT * tQComponent[NO_OF_VIEWS_IN_MEMORY]; }; class ClassViewLoader: public QObject { Q_OBJECT public: explicit ClassViewLoader(QObject *parent = 0); //...... other variables and methods private: //...... other variables and methods void LoadUnloadView(QString strQMLPath); LOADED_VIEWS m_tLoadedViews; };
Implementation of LoadUnloadView() is :
//...some code here for data validation QObject * l_pitsCQObjectBase = NULL; /*GetQMLComponent() function returns the instance of a class that owns the QML. In this case, it is the instance of ClassA. */ l_pitsCQObjectBase = GetQMLComponent(strQMLPath); if ( NULL == m_pitsQQuickView ) { m_pitsQQuickView = new QQuickView; m_pitsQQuickView->setFlags(Qt::FramelessWindowHint); qDebug() << "setting the context property" << endl; m_pitsQQuickView->rootContext()->setContextProperty( "instanceofClassA", l_pitsCQObjectBase); m_pitsQQuickView->setSource(QUrl(l_strQmlPath)); m_pitsQQuickView->show(); } //... other code to store the data and unload the view
When I execute this code, it core dumps intermittently. And the last log that I can see is : "setting the context property" .
back trace of the core dump shows like this :
#0 magazine_cache_pop_magazine (mem_size=8) at gslice.c:733 733 gslice.c: No such file or directory. in gslice.c (gdb) bt #0 magazine_cache_pop_magazine (mem_size=8) at gslice.c:733 #1 thread_memory_magazine1_reload (mem_size=8) at gslice.c:801 #2 g_slice_alloc (mem_size=8) at gslice.c:1014 #3 0xb3ba4817 in g_wakeup_new () at gwakeup.c:141 #4 0xb3b5bbc0 in g_main_context_new () at gmain.c:653 #5 0xb605b9f6 in QEventDispatcherGlibPrivate::QEventDispatcherGlibPrivate(_GMainContext*) () from /opt/jlr/lib/libQt5Core.so.5 #6 0xb605bafc in QEventDispatcherGlib::QEventDispatcherGlib(QObject*) () from /opt/jlr/lib/libQt5Core.so.5 #7 0xb5e362e1 in QThreadPrivate::createEventDispatcher(QThreadData*) () from /opt/jlr/lib/libQt5Core.so.5 #8 0xb5e36bc8 in QThreadPrivate::start(void*) () from /opt/jlr/lib/libQt5Core.so.5 #9 0xb5d88e19 in start_thread () from /lib/libpthread.so.0 #10 0xb5be6ffe in clone () from /lib/libc.so.6
However, if I, either comment the line
m_pitsQQuickView->rootContext()->setContextProperty( "instanceofClassA", l_pitsCQObjectBase);
Or implement the LoadUnloadView() function as :
//...some code here for data validation //QObject * l_pitsCQObjectBase = NULL; ClassA * l_pitsClassA = new ClassA; /*GetQMLComponent() function returns the instance of a class that owns the QML. In this case, it is the instance of ClassA. */ //l_pitsCQObjectBase = GetQMLComponent(strQMLPath); if ( NULL == m_pitsQQuickView ) { m_pitsQQuickView = new QQuickView; m_pitsQQuickView->setFlags(Qt::FramelessWindowHint); qDebug() << "setting the context property" << endl; m_pitsQQuickView->rootContext()->setContextProperty( "instanceofClassA", l_pitsClassA); m_pitsQQuickView->setSource(QUrl(l_strQmlPath)); m_pitsQQuickView->show(); } //... other code to store the data and unload the view
I will not see any core dumps. And, I don't want to follow the second approach because of several reasons.
Can anyone please help me in root-causing the issue. Also, please let me know the approach that I have taken to design the code is wrong.
Thanks in advance.
-
-
Hi and welcome to devnet,
Did you check that
l_pitsCQObjectBase
is not null before setting it as context property ?Why are you doing these two separated classes ? Did you read the QtQml cpp integration chapter of Qt's documentation ?
-
Hi SGaist,
Thank you for your response!
@SGaist said in Segmentation fault when calling setContextProperty!!!:
Hi and welcome to devnet,
Did you check that
l_pitsCQObjectBase
is not null before setting it as context property ?Yes, I am sure that
l_pitsCQObjectBase
is not NULL. In fact, for debugging purposes, I have changed the implementation ofGetQMLComponent(strQMLPath);
to return only instance ofClassA
, and yet, I have observed the crash. :( :(Why are you doing these two separated classes ?
ClassViewLoader
is the central component that is responsible for loading and unloading multiple qml views. As I have multiple number of qml views (say, more than 20 views), I have kept a central component to handle it. And, also, C++ classes corresponding to QML should only know
a. how to update data to QML and
b. receive data from QML and pass it toClassViewLoader
to pass it to other layers of my project.Do you see any flaw here?
Did you read the QtQml cpp integration chapter of Qt's documentation ?
Yes. But,initially, my thought was to expose the object of C++ to QML environment and not the C++ class itself. Hence I have not used
qmlRegister*() APIs
.I want to understand where I am doing a mistake here!! :( :(
-
Not NULL and containing something valid is two different things. You should really check that it's pointing to something valid.
All I see here is a pretty hight level of complexity that might not be needed but I don't know your project so I can't really comment more.
-
@SGaist said in Segmentation fault when calling setContextProperty!!!:
Not NULL and containing something valid is two different things. You should really check that it's pointing to something valid.
Hi SGaist,
Apologies, I have taken a while to come back.
I was sure
l_pitsCQObjectBase
was pointing to valid address when I said it was not NULL.It seems to be an issue that is specific to the hardware and the version of OS that we are using. Because, I have used the same set of code in different versions of qt in desktop and it has never crashed.
I will continue to investigate the issue in the target environment that I have and I am marking this thread as solved.
Thank you for your support.