Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

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.


  • Lifetime Qt Champion

    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 of GetQMLComponent(strQMLPath); to return only instance of ClassA, 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 to ClassViewLoader 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!! :( :(


  • Lifetime Qt Champion

    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.


Log in to reply