Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Passing custom type pointers between QML and threads via signals and slots cause app to crash
QtWS25 Last Chance

Passing custom type pointers between QML and threads via signals and slots cause app to crash

Scheduled Pinned Locked Moved Solved General and Desktop
qthreadqmlmultithreadingqvariantsignals & slots
13 Posts 4 Posters 3.6k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Matthew11
    20 May 2019, 13:16

    Hi, as topic partially described, I send pointers to my custom type object, which has 3 members (int, int and QVariant) via sig/slot between the main thread and the worker thread. I use the Controller - Worker approach from qt docs.

    Everything was fine when I have two int members in class, and it started crashing (SIGSEGV) since I have added QVariant member to exchange data between QML and C++.

    I'm guessing that crash is caused by accessing the shared resource (my custom class instance). I tried to add some serialization using QMutex, with and without QMutexLocker, QReadWriteLocker but the result was the same - crash. I also tried to protect the shared resource by applying Monitor construct wiki protecting the data with mutexes, but it also didn't work. At the moment I'm out of ideas and look for any help. Thanks in advance.

    Here is my code (plain text and link to git clone), program will probably crash after clicking the button or few spontaneous clicks. ContractorTask is my custom which I want to send using pointers.

    source:

    // ContractorTask.h
    
    #ifndef TASK_H
    #define TASK_H
    
    #include <QObject>
    #include <QVariant>
    #include <QThread>
    #include <QDebug>
    
    class ContractorTask : public QObject
    {
        Q_OBJECT
    
    public:
        explicit ContractorTask(QObject *parent = nullptr) :
            QObject(parent),
            taskID(-1),
            contractorID(-1),
            data("")
        {
            // ...
        }
    
        Q_INVOKABLE int getTaskID()
        {
            qDebug() << "getTaskID()" << QThread::currentThreadId();
            return taskID;
        }
    
        Q_INVOKABLE void setTaskID(int _ID)
        {
            qDebug() << "setTaskID()" << QThread::currentThreadId();
            taskID = _ID;
        }
    
        Q_INVOKABLE int getConctractorID()
        {
            qDebug() << "getConctractorID()" << QThread::currentThreadId();
            return contractorID;
        }
    
        Q_INVOKABLE void setContractorID(int _ID)
        {
            qDebug() << "setContractorID()" << QThread::currentThreadId();
            contractorID = _ID;
        }
    
        Q_INVOKABLE QVariant getData()
        {
            qDebug() << "getData()" << QThread::currentThreadId();
            return data;
        }
    
        Q_INVOKABLE void setData(QVariant _data)
        {
            qDebug() << "setData()" << QThread::currentThreadId();
            data = _data;
        }
    
    private:
        int taskID;
        int contractorID;
        QVariant data;
    };
    
    #endif // TASK_H
    
    // Contractor.h
    
    #ifndef CONTRACTOR_H
    #define CONTRACTOR_H
    
    #include <QObject>
    #include <QQmlEngine>
    #include <QThread>
    #include <QMutex>
    
    #include <ContractorTask.h>
    
    //#define CONTRACTOR_DEBUG_LOCK
    
    class Contractor : public QObject
    {
        Q_OBJECT
    
    public:
        Contractor(int _ID, QObject* parent = nullptr);
        ~Contractor();
    
        enum class Tasks : int
        {
            NOT_DEFINED = -1,
            Q_LIST_VARIANTS_TO_QML,
            GET_QVARIANT_FROM_QML
        };
    
        Q_ENUMS(Tasks)
    
        inline static void registerTasks()
        {
            qmlRegisterUncreatableType<Contractor>("Tasks", 1, 0, "ContractorTasks", "ContractorTask is uncreatable in QML");
        }
    
        int getID()
        {
            return ID;
        }
    
    public slots:
        void executeTask(ContractorTask* _task);
    
    signals:
        void finished();
        void taskStarted(ContractorTask* _task);
        void taskFinished(ContractorTask* _task);
    
    private:
        int ID;
    
    #ifndef CONTRACTOR_DEBUG_LOCK
        Qt::HANDLE mainThreadID;
    #endif
    };
    #endif // CONTRACTOR_H
    
    //Contractor.cpp
    
    #include "Contractor.h"
    
    #include <QDebug>
    #include <QThread>
    
    Contractor::Contractor(int _ID, QObject *parent) :
        QObject(parent),
        ID(_ID)
    {
    #ifndef CONTRACTOR_DEBUG_LOCK
        mainThreadID = QThread::currentThreadId();
    #endif
    }
    
    Contractor::~Contractor()
    {
        // ...
    
        qDebug() << "Cleaning SerialPortContractor...";
    }
    
    void Contractor::executeTask(ContractorTask* _task)
    {
        emit(taskStarted(_task));
    
        qDebug() << "\tCONTRACTOR STARTED";
    
        int localContractorID = _task->getConctractorID();
    
        if(localContractorID != getID())
        {
            qDebug() << "Not mine ID: " << localContractorID << "discarding";
            return;
        }
    
        qDebug() << "Emiting signal from Contractor";
        emit(taskStarted(_task));
    
        int localTaskID = _task->getTaskID();
        QVariant localData = _task->getData();
    
        QList<QVariant> _params;
        QList<float> _floats;
        _params = localData.value<QList<QVariant>>();
    
        for(auto item : _params)
        {
            _floats << item.toFloat();
        }
    
    #ifndef CONTRACTOR_DEBUG_LOCK
        qDebug() << "Main ThreadID =" << mainThreadID << "my ThreadID =" << QThread::currentThreadId();
    #endif
    
        switch(static_cast<Tasks>(localTaskID))
        {
        case Tasks::Q_LIST_VARIANTS_TO_QML :
        {
            QList<QVariant> _params;
            _params.append(12.5F);
            _params.append(14.36F);
    
            QVariant _data = _params;
    
            _task->setData(_data);
        }
            break;
        case Tasks::GET_QVARIANT_FROM_QML:
        {
            int i = 0;
            for(auto item : _floats)
            {
                qDebug() << "C++ item" << i++ << "value" << item;
            }
        }
            break;
        default:
        {
    #ifndef CONTRACTOR_DEBUG_LOCK
            qDebug() << "Oh... I don't have these one :(";
    #endif
        }
        }
    
        emit(taskFinished(_task));
    
        qDebug() << "\tCONTRACTOR ENDED";
    }
    
    // Controller.h
    
    #ifndef CONTROLLERv2_H
    #define CONTROLLERv2_H
    
    #include <QObject>
    #include <QThread>
    #include <QDebug>
    
    #include <Contractor.h>
    #include <ContractorTask.h>
    
    class Controller : public QObject
    {
        Q_OBJECT
        QThread workerThread;
    
    public:
        Controller()
        {
            Contractor *worker = new Contractor(0);
            worker->moveToThread(&workerThread);
            connect(&workerThread, &QThread::finished, worker, &QObject::deleteLater);
            connect(this, &Controller::startTask, worker, &Contractor::executeTask);
            connect(worker, &Contractor::taskFinished, this, &Controller::handleResults);
            workerThread.start();
        }
    
        ~Controller()
        {
            workerThread.quit();
            workerThread.wait();
        }
    
    signals:
        void startTask(ContractorTask*);
    
    public slots:
        void handleResults(ContractorTask* _task)
        {
            qDebug() << _task->getTaskID() << _task->getConctractorID() << _task->getData();
        }
    };
    #endif // CONTROLLERv2_H
    
    // main.cpp
    
    #include <QGuiApplication>
    #include <QQmlApplicationEngine>
    #include <Controller.h>
    #include <QQmlContext>
    
    int main(int argc, char *argv[])
    {
        QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    
        QGuiApplication app(argc, argv);
    
        Contractor::registerTasks();
        Controller TaskController;
        ContractorTask Task;
    
        QQmlApplicationEngine engine;
        engine.rootContext()->setContextProperty("TaskController", &TaskController);
        engine.rootContext()->setContextProperty("Task", &Task);
    
        const QUrl url(QStringLiteral("qrc:/main.qml"));
        QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
                         &app, [url](QObject *obj, const QUrl &objUrl) {
            if (!obj && url == objUrl)
                QCoreApplication::exit(-1);
        }, Qt::QueuedConnection);
        engine.load(url);
    
        return app.exec();
    }
    
    // main.qml
    
    import QtQuick 2.12
    import QtQuick.Controls 2.5
    
    import Tasks 1.0
    
    ApplicationWindow {
        id: applicationWindow
        visible: true
        width: 640
        height: 480
        title: qsTr("Test")
    
        Button {
            id: button
            text: qsTr("Button")
            anchors.verticalCenter: parent.verticalCenter
            anchors.horizontalCenter: parent.horizontalCenter
    
            onClicked: {
                var items = [1.25, 2.12345, 2.2, 1.25, 2.12345, 2.2, 1.25, 2.12345, 2.2, 1.25, 2.12345, 2.2]
    
                Task.setData(items)
                runTaskFromQML(ContractorTasks.GET_QVARIANT_FROM_QML, 0)
                runTaskFromQML(ContractorTasks.GET_QVARIANT_FROM_QML, 0)
                runTaskFromQML(ContractorTasks.GET_QVARIANT_FROM_QML, 0)
                runTaskFromQML(ContractorTasks.GET_QVARIANT_FROM_QML, 0)
            }
        }
    
        function runTaskFromQML(_taskId, _contractorID)
        {
            console.log("Running worker task from QML, ID = ", _taskId, " Contractor ID = ", _contractorID)
    
            Task.setTaskID(_taskId)
            Task.setContractorID(_contractorID)
            TaskController.startTask(Task)
        }
    }
    
    // .pro
    
    QT += quick
    CONFIG += c++11
    
    DEFINES += QT_DEPRECATED_WARNINGS
    
    SOURCES += \
            Contractor.cpp \
            main.cpp
    
    RESOURCES += qml.qrc
    
    # Default rules for deployment.
    qnx: target.path = /tmp/$${TARGET}/bin
    else: unix:!android: target.path = /opt/$${TARGET}/bin
    !isEmpty(target.path): INSTALLS += target
    
    HEADERS += \
        Contractor.h \
        ContractorTask.h \
        Controller.h
    
    kshegunovK Offline
    kshegunovK Offline
    kshegunov
    Moderators
    wrote on 20 May 2019, 21:40 last edited by
    #3

    @Matthew11 said in Passing custom type pointers between threads via signals and slots cause app to crash:

    I'm guessing that crash is caused by accessing the shared resource (my custom class instance). I tried to add some serialization using QMutex, with and without QMutexLocker, QReadWriteLocker but the result was the same - crash.

    Crashes have stack traces. Please provide one. Also as a hint:

    Q_INVOKABLE void setData(QVariant _data)
    {
        Q_ASSERT(QThread::currentThread() == thread());
    
        qDebug() << "setData()" << QThread::currentThreadId();
        data = _data;
    }
    

    Read and abide by the Qt Code of Conduct

    M 1 Reply Last reply 21 May 2019, 09:39
    3
    • SGaistS SGaist
      20 May 2019, 21:09

      Hi,

      What is the exact goal for that QVariant ?

      M Offline
      M Offline
      Matthew11
      wrote on 21 May 2019, 08:47 last edited by
      #4

      @SGaist said in Passing custom type pointers between threads via signals and slots cause app to crash:

      What is the exact goal for that QVariant ?

      Well, simply speaking, to pass various data between QML and C++ (floats, integers, QStrings and any that will be needed) within the ContractorTask object.

      Use of case: The UI send request (with taskID, contractorID (both ints) and data (QVariant) as ContractorTask object) then the specific Contractor (another thread) run specific code and return the result (QVariant) which is also included in ContractorTask object. Then in QML, I know which task was started and ended and with what data -> the UI can be updated. As well in the opposite direction (C++ received event, then sends data to QML). I also have interfaces (not included in the sources that I provided) for Contractor and Controller which relay on ContractorTask object and simplifies things with making new Contractors passing them to Controller which takes care of connections, clean up (things that Controller does).

      1 Reply Last reply
      0
      • kshegunovK kshegunov
        20 May 2019, 21:40

        @Matthew11 said in Passing custom type pointers between threads via signals and slots cause app to crash:

        I'm guessing that crash is caused by accessing the shared resource (my custom class instance). I tried to add some serialization using QMutex, with and without QMutexLocker, QReadWriteLocker but the result was the same - crash.

        Crashes have stack traces. Please provide one. Also as a hint:

        Q_INVOKABLE void setData(QVariant _data)
        {
            Q_ASSERT(QThread::currentThread() == thread());
        
            qDebug() << "setData()" << QThread::currentThreadId();
            data = _data;
        }
        
        M Offline
        M Offline
        Matthew11
        wrote on 21 May 2019, 09:39 last edited by Matthew11
        #5

        @kshegunov said in Passing custom type pointers between threads via signals and slots cause app to crash:

        Crashes have stack traces. Please provide one. Also as a hint:
        Q_ASSERT(QThread::currentThread() == thread());

        So, If I understand it correctly, it gives me insights where and when another thread is working on resources from another thread? So it happens when Contractor is working on _task in Contractor::executeTask(ContractorTask*) which is "normal" in this case. And these places should be protected. Am I right, that's the hint?

        Returning to stack traces, I generated them for the same code included before. App crashes seem to be connected with QV4Object. 3'rd and 6'th seem to be more common. Is the table content enough or will it be better with screenshots?

        -->1<--
        
        1   QV4::Object::get                           qv4object_p.h                308  0x7ffff714c2fc 
        2   QV4::Runtime::method_callProperty          qv4runtime.cpp               1376 0x7ffff714c2fc 
        3   QV4::Moth::VME::interpret                  qv4vme_moth.cpp              718  0x7ffff70e3f90 
        4   QV4::Moth::VME::exec                       qv4vme_moth.cpp              441  0x7ffff70e7cc4 
        5   QV4::ArrowFunction::virtualCall            qv4functionobject.cpp        513  0x7ffff7080720 
        6   QV4::FunctionObject::call                  qv4functionobject_p.h        202  0x7ffff71474a3 
        7   QV4::Runtime::method_callName              qv4runtime.cpp               1346 0x7ffff71474a3 
        8   QV4::Moth::VME::interpret                  qv4vme_moth.cpp              745  0x7ffff70e3e37 
        9   QV4::Moth::VME::exec                       qv4vme_moth.cpp              441  0x7ffff70e7cc4 
        10  QV4::Function::call                        qv4function.cpp              68   0x7ffff707fade 
        11  QQmlJavaScriptExpression::evaluate         qqmljavascriptexpression.cpp 216  0x7ffff71e7eb8 
        12  QQmlBoundSignalExpression::evaluate        qqmlboundsignal.cpp          225  0x7ffff718aa52 
        13  QQmlBoundSignal_callback                   qqmlboundsignal.cpp          358  0x7ffff718bf53 
        14  QQmlNotifier::emitNotify                   qqmlnotifier.cpp             106  0x7ffff71c9cf4 
        15  QQmlData::signalEmitted                    qqmlengine.cpp               880  0x7ffff716e274 
        16  QMetaObject::activate                      qobject.cpp                  3648 0x7ffff6a20c92 
        17  QQuickAbstractButtonPrivate::handleRelease qquickabstractbutton.cpp     179  0x7fffd0d71ca8 
        18  QQuickControl::mouseReleaseEvent           qquickcontrol.cpp            2099 0x7fffd0d8c9f5 
        19  QQuickItem::event                          qquickitem.cpp               8096 0x7fffd22c98de 
        20  QCoreApplication::notifyInternal2          qcoreapplication.cpp         1061 0x7ffff69f4c18         
        
        --> 2 <--
        
        1   QV4::IdentifierHash::lookup         qv4identifier.cpp            173  0x7ffff7058c28 
        2   QV4::IdentifierHash::value          qv4identifier_p.h            165  0x7ffff70a6bc5 
        3   QV4::QQmlContextWrapper::virtualGet qv4qmlcontext.cpp            196  0x7ffff70a6bc5 
        4   QV4::Object::get                    qv4object_p.h                314  0x7ffff7055b65 
        5   QV4::ExecutionContext::getProperty  qv4context.cpp               360  0x7ffff7055b65 
        6   QV4::Runtime::method_loadName       qv4runtime.cpp               985  0x7ffff7143df0 
        7   QV4::Moth::VME::interpret           qv4vme_moth.cpp              548  0x7ffff70e413e 
        8   QV4::Moth::VME::exec                qv4vme_moth.cpp              441  0x7ffff70e7cc4 
        9   QV4::ArrowFunction::virtualCall     qv4functionobject.cpp        513  0x7ffff7080720 
        10  QV4::FunctionObject::call           qv4functionobject_p.h        202  0x7ffff71474a3 
        11  QV4::Runtime::method_callName       qv4runtime.cpp               1346 0x7ffff71474a3 
        12  QV4::Moth::VME::interpret           qv4vme_moth.cpp              745  0x7ffff70e3e37 
        13  QV4::Moth::VME::exec                qv4vme_moth.cpp              441  0x7ffff70e7cc4 
        14  QV4::Function::call                 qv4function.cpp              68   0x7ffff707fade 
        15  QQmlJavaScriptExpression::evaluate  qqmljavascriptexpression.cpp 216  0x7ffff71e7eb8 
        16  QQmlBoundSignalExpression::evaluate qqmlboundsignal.cpp          225  0x7ffff718aa52 
        17  QQmlBoundSignal_callback            qqmlboundsignal.cpp          358  0x7ffff718bf53 
        18  QQmlNotifier::emitNotify            qqmlnotifier.cpp             106  0x7ffff71c9cf4 
        19  QQmlData::signalEmitted             qqmlengine.cpp               880  0x7ffff716e274 
        20  QMetaObject::activate               qobject.cpp                  3648 0x7ffff6a20c92 
        
        --> 3 <--
        
        1  QV4::Heap::String::append                        qv4string.cpp                235  0x7ffff714dcdc 
        2  QV4::Heap::String::simplifyString                qv4string.cpp                184  0x7ffff714de22 
        3  QV4::String::createPropertyKeyImpl               qv4string.cpp                172  0x7ffff714dfcb 
        4  QV4::StringOrSymbol::createPropertyKey           qv4string_p.h                311  0x7ffff714c324 
        5  QV4::StringOrSymbol::toPropertyKey               qv4string_p.h                316  0x7ffff714c324 
        6  QV4::Object::get                                 qv4object_p.h                308  0x7ffff714c324 
        7  QV4::Runtime::method_callProperty                qv4runtime.cpp               1376 0x7ffff714c324 
        8  QV4::Moth::VME::interpret                        qv4vme_moth.cpp              718  0x7ffff70e3f90 
        9  QV4::Moth::VME::exec                             qv4vme_moth.cpp              441  0x7ffff70e7cc4 
        10 QV4::ArrowFunction::virtualCall                  qv4functionobject.cpp        513  0x7ffff7080720 
        11 QV4::FunctionObject::call                        qv4functionobject_p.h        202  0x7ffff71474a3 
        12 QV4::Runtime::method_callName                    qv4runtime.cpp               1346 0x7ffff71474a3 
        13 QV4::Moth::VME::interpret                        qv4vme_moth.cpp              745  0x7ffff70e3e37 
        14 QV4::Moth::VME::exec                             qv4vme_moth.cpp              441  0x7ffff70e7cc4 
        15 QV4::Function::call                              qv4function.cpp              68   0x7ffff707fade 
        16 QQmlJavaScriptExpression::evaluate               qqmljavascriptexpression.cpp 216  0x7ffff71e7eb8 
        17 QQmlBoundSignalExpression::evaluate              qqmlboundsignal.cpp          225  0x7ffff718aa52 
        18 QQmlBoundSignal_callback                         qqmlboundsignal.cpp          358  0x7ffff718bf53 
        19 QQmlNotifier::emitNotify                         qqmlnotifier.cpp             106  0x7ffff71c9cf4 
        20 QQmlData::signalEmitted                          qqmlengine.cpp               880  0x7ffff716e274 
        21 QMetaObject::activate                            qobject.cpp                  3648 0x7ffff6a20c92 
        22 QQuickAbstractButtonPrivate::handleRelease       qquickabstractbutton.cpp     179  0x7fffd0d71ca8 
        23 QQuickControl::mouseReleaseEvent                 qquickcontrol.cpp            2099 0x7fffd0d8c9f5 
        24 QQuickItem::event                                qquickitem.cpp               8096 0x7fffd22c98de 
        25 QCoreApplication::notifyInternal2                qcoreapplication.cpp         1061 0x7ffff69f4c18 
        26 QCoreApplication::sendEvent                      qcoreapplication.cpp         1451 0x7ffff69f4dce 
        27 QQuickWindowPrivate::deliverMouseEvent           qquickwindow.cpp             1784 0x7fffd22e23bf 
        28 QQuickWindowPrivate::deliverPointerEvent         qquickwindow.cpp             2346 0x7fffd22e36fb 
        29 QQuickWindowPrivate::handleMouseEvent            qquickwindow.cpp             2210 0x7fffd22e4535 
        30 QWindow::event                                   qwindow.cpp                  2336 0x7ffff77044eb 
        31 QQuickWindow::event                              qquickwindow.cpp             1673 0x7fffd22e54e5 
        32 QCoreApplication::notifyInternal2                qcoreapplication.cpp         1061 0x7ffff69f4c18 
        33 QCoreApplication::sendSpontaneousEvent           qcoreapplication.cpp         1463 0x7ffff69f4dde 
        34 QGuiApplicationPrivate::processMouseEvent        qguiapplication.cpp          2102 0x7ffff76f91e7 
        35 QGuiApplicationPrivate::processWindowSystemEvent qguiapplication.cpp          1837 0x7ffff76fa795 
        36 QWindowSystemInterface::sendWindowSystemEvents   qwindowsysteminterface.cpp   1068 0x7ffff76d644b 
        37 xcbSourceDispatch                                qxcbeventdispatcher.cpp      105  0x7ffff014767a 
        38 g_main_context_dispatch                                                            0x7ffff24dc417 
        39 ??                                                                                 0x7ffff24dc650 
        40 g_main_context_iteration                                                           0x7ffff24dc6dc 
        41 QEventDispatcherGlib::processEvents              qeventdispatcher_glib.cpp    422  0x7ffff6a4bdcf 
        42 QEventLoop::exec                                 qeventloop.cpp               225  0x7ffff69f357a 
        43 QCoreApplication::exec                           qcoreapplication.cpp         1364 0x7ffff69fbf80 
        44 main                                             main.cpp                     28   0x55555555be66 
        
        --> 4 <--
        
        
        1  QV4::Object::get                                                                                                                          qv4object_p.h             310  0x7ffff713cee4 
        2  objectToVariant                                                                                                                           qv4engine.cpp             1389 0x7ffff713cee4 
        3  toVariant                                                                                                                                 qv4engine.cpp             1359 0x7ffff713d949 
        4  QV4::ExecutionEngine::toVariant                                                                                                           qv4engine.cpp             1252 0x7ffff713dc10 
        5  QJSValue::toVariant                                                                                                                       qjsvalue.cpp              714  0x7ffff70521e4 
        6  convertJSValueToVariantType<QList<QVariant>>                                                                                              qv8engine.cpp             100  0x7ffff721b4c1 
        7  QtPrivate::ConverterFunctor<QJSValue, QList<QVariant>, QList<QVariant> ( *)(QJSValue const&)>::convert                                    qmetatype.h               398  0x7ffff721b162 
        8  QMetaType::convert                                                                                                                        qmetatype.cpp             739  0x7ffff6a0b36d 
        9  (anonymous namespace)::convert                                                                                                            qvariant.cpp              393  0x7ffff6a3ada1 
        10 QtPrivate::QVariantValueHelper<QList<QVariant>>::metaType                                                                                 qvariant.h                725  0x55555555a42e 
        11 QtPrivate::MetaTypeInvoker<QtPrivate::QVariantValueHelper<QList<QVariant>>, QVariant const&, QList<QVariant>>::invoke                     qvariant.h                115  0x5555555594c7 
        12 QtPrivate::QVariantValueHelperInterface<QList<QVariant>>::invoke                                                                          qvariant.h                793  0x5555555589f0 
        13 qvariant_cast<QList<QVariant>>                                                                                                            qvariant.h                860  0x55555555a536 
        14 QVariant::value<QList<QVariant>>                                                                                                          qvariant.h                362  0x555555559576 
        15 Contractor::executeTask                                                                                                                   Contractor.cpp            44   0x555555557a9a 
        16 QtPrivate::FunctorCall<QtPrivate::IndexesList<0>, QtPrivate::List<ContractorTask *>, void, void (Contractor:: *)(ContractorTask *)>::call qobjectdefs_impl.h        152  0x55555555e49b 
        17 QtPrivate::FunctionPointer<void (Contractor:: *)(ContractorTask *)>::call<QtPrivate::List<ContractorTask *>, void>                        qobjectdefs_impl.h        185  0x55555555e179 
        18 QtPrivate::QSlotObject<void (Contractor:: *)(ContractorTask *), QtPrivate::List<ContractorTask *>, void>::impl                            qobjectdefs_impl.h        414  0x55555555de01 
        19 QObject::event                                                                                                                            qobject.cpp               1249 0x7ffff6a21581 
        20 QCoreApplication::notifyInternal2                                                                                                         qcoreapplication.cpp      1061 0x7ffff69f4c18 
        21 QCoreApplication::sendEvent                                                                                                               qcoreapplication.cpp      1451 0x7ffff69f4dce 
        22 QCoreApplicationPrivate::sendPostedEvents                                                                                                 qcoreapplication.cpp      1800 0x7ffff69f7647 
        23 QCoreApplication::sendPostedEvents                                                                                                        qcoreapplication.cpp      1654 0x7ffff69f7b28 
        24 postEventSourceDispatch                                                                                                                   qeventdispatcher_glib.cpp 276  0x7ffff6a4c793 
        25 g_main_context_dispatch                                                                                                                                                  0x7ffff24dc417 
        26 ??                                                                                                                                                                       0x7ffff24dc650 
        27 g_main_context_iteration                                                                                                                                                 0x7ffff24dc6dc 
        28 QEventDispatcherGlib::processEvents                                                                                                       qeventdispatcher_glib.cpp 422  0x7ffff6a4bdcf 
        29 QEventLoop::exec                                                                                                                          qeventloop.cpp            225  0x7ffff69f357a 
        30 QThread::exec                                                                                                                             qthread.cpp               531  0x7ffff682b7dc 
        31 QThreadPrivate::start                                                                                                                     qthread_unix.cpp          361  0x7ffff682cd13 
        32 start_thread                                                                                                                              pthread_create.c          463  0x7ffff5bdd6db 
        33 clone                                                                                                                                     clone.S                   95   0x7ffff5f1688f                                            
        
        --> 5 <--
        
        1   QV4::Object::ownPropertyKeys                                                                                                              qv4object_p.h         367  0x7ffff713cbdd 
        2   QV4::ObjectIterator::ObjectIterator                                                                                                       qv4objectiterator_p.h 80   0x7ffff713cbdd 
        3   objectToVariant                                                                                                                           qv4engine.cpp         1397 0x7ffff713cbdd 
        4   toVariant                                                                                                                                 qv4engine.cpp         1359 0x7ffff713d949 
        5   QV4::ExecutionEngine::toVariant                                                                                                           qv4engine.cpp         1252 0x7ffff713dc10 
        6   QJSValue::toVariant                                                                                                                       qjsvalue.cpp          714  0x7ffff70521e4 
        7   convertJSValueToVariantType<QList<QVariant>>                                                                                              qv8engine.cpp         100  0x7ffff721b4c1 
        8   QtPrivate::ConverterFunctor<QJSValue, QList<QVariant>, QList<QVariant> ( *)(QJSValue const&)>::convert                                    qmetatype.h           398  0x7ffff721b162 
        9   QMetaType::convert                                                                                                                        qmetatype.cpp         739  0x7ffff6a0b36d 
        10  (anonymous namespace)::convert                                                                                                            qvariant.cpp          393  0x7ffff6a3ada1 
        11  QtPrivate::QVariantValueHelper<QList<QVariant>>::metaType                                                                                 qvariant.h            725  0x55555555a42e 
        12  QtPrivate::MetaTypeInvoker<QtPrivate::QVariantValueHelper<QList<QVariant>>, QVariant const&, QList<QVariant>>::invoke                     qvariant.h            115  0x5555555594c7 
        13  QtPrivate::QVariantValueHelperInterface<QList<QVariant>>::invoke                                                                          qvariant.h            793  0x5555555589f0 
        14  qvariant_cast<QList<QVariant>>                                                                                                            qvariant.h            860  0x55555555a536 
        15  QVariant::value<QList<QVariant>>                                                                                                          qvariant.h            362  0x555555559576 
        16  Contractor::executeTask                                                                                                                   Contractor.cpp        44   0x555555557a9a 
        17  QtPrivate::FunctorCall<QtPrivate::IndexesList<0>, QtPrivate::List<ContractorTask *>, void, void (Contractor:: *)(ContractorTask *)>::call qobjectdefs_impl.h    152  0x55555555e49b 
        18  QtPrivate::FunctionPointer<void (Contractor:: *)(ContractorTask *)>::call<QtPrivate::List<ContractorTask *>, void>                        qobjectdefs_impl.h    185  0x55555555e179 
        19  QtPrivate::QSlotObject<void (Contractor:: *)(ContractorTask *), QtPrivate::List<ContractorTask *>, void>::impl                            qobjectdefs_impl.h    414  0x55555555de01 
        20  QObject::event                                                                                                                            qobject.cpp           1249 0x7ffff6a21581 
        ... <More>                                                                                                                                                                              
        
        --> 6 <--
        
        1   QV4::Heap::String::append                  qv4string.cpp         235  0x7ffff714dcdc 
        2   QV4::Heap::String::simplifyString          qv4string.cpp         184  0x7ffff714de22 
        3   QV4::Heap::StringOrSymbol::createHashValue qv4string.cpp         245  0x7ffff714e185 
        4   QV4::Heap::StringOrSymbol::hashValue       qv4string_p.h         97   0x7ffff70ceb35 
        5   QV4::Heap::String::isEqualTo               qv4string_p.h         128  0x7ffff70ceb35 
        6   QV4::String::equals                        qv4string_p.h         203  0x7ffff70cb3db 
        7   QV4::QObjectWrapper::getQmlProperty        qv4qobjectwrapper.cpp 283  0x7ffff70cb3db 
        8   QV4::QObjectWrapper::getQmlProperty        qv4qobjectwrapper.cpp 414  0x7ffff70cbc4e 
        9   QV4::QQmlContextWrapper::virtualGet        qv4qmlcontext.cpp     246  0x7ffff70a6c66 
        10  QV4::Object::get                           qv4object_p.h         314  0x7ffff7055b65 
        11  QV4::ExecutionContext::getProperty         qv4context.cpp        360  0x7ffff7055b65 
        12  QV4::Runtime::method_loadName              qv4runtime.cpp        985  0x7ffff7143df0 
        13  QV4::Moth::VME::interpret                  qv4vme_moth.cpp       548  0x7ffff70e413e 
        14  QV4::Moth::VME::exec                       qv4vme_moth.cpp       441  0x7ffff70e7cc4 
        15  QV4::ArrowFunction::virtualCall            qv4functionobject.cpp 513  0x7ffff7080720 
        16  QV4::FunctionObject::call                  qv4functionobject_p.h 202  0x7ffff71474a3 
        17  QV4::Runtime::method_callName              qv4runtime.cpp        1346 0x7ffff71474a3 
        18  QV4::Moth::VME::interpret                  qv4vme_moth.cpp       745  0x7ffff70e3e37 
        19  QV4::Moth::VME::exec                       qv4vme_moth.cpp       441  0x7ffff70e7cc4 
        20  QV4::Function::call                        qv4function.cpp       68   0x7ffff707fade 
        ... <More>                                                                               
        
        
        kshegunovK 1 Reply Last reply 21 May 2019, 19:13
        0
        • M Matthew11
          21 May 2019, 09:39

          @kshegunov said in Passing custom type pointers between threads via signals and slots cause app to crash:

          Crashes have stack traces. Please provide one. Also as a hint:
          Q_ASSERT(QThread::currentThread() == thread());

          So, If I understand it correctly, it gives me insights where and when another thread is working on resources from another thread? So it happens when Contractor is working on _task in Contractor::executeTask(ContractorTask*) which is "normal" in this case. And these places should be protected. Am I right, that's the hint?

          Returning to stack traces, I generated them for the same code included before. App crashes seem to be connected with QV4Object. 3'rd and 6'th seem to be more common. Is the table content enough or will it be better with screenshots?

          -->1<--
          
          1   QV4::Object::get                           qv4object_p.h                308  0x7ffff714c2fc 
          2   QV4::Runtime::method_callProperty          qv4runtime.cpp               1376 0x7ffff714c2fc 
          3   QV4::Moth::VME::interpret                  qv4vme_moth.cpp              718  0x7ffff70e3f90 
          4   QV4::Moth::VME::exec                       qv4vme_moth.cpp              441  0x7ffff70e7cc4 
          5   QV4::ArrowFunction::virtualCall            qv4functionobject.cpp        513  0x7ffff7080720 
          6   QV4::FunctionObject::call                  qv4functionobject_p.h        202  0x7ffff71474a3 
          7   QV4::Runtime::method_callName              qv4runtime.cpp               1346 0x7ffff71474a3 
          8   QV4::Moth::VME::interpret                  qv4vme_moth.cpp              745  0x7ffff70e3e37 
          9   QV4::Moth::VME::exec                       qv4vme_moth.cpp              441  0x7ffff70e7cc4 
          10  QV4::Function::call                        qv4function.cpp              68   0x7ffff707fade 
          11  QQmlJavaScriptExpression::evaluate         qqmljavascriptexpression.cpp 216  0x7ffff71e7eb8 
          12  QQmlBoundSignalExpression::evaluate        qqmlboundsignal.cpp          225  0x7ffff718aa52 
          13  QQmlBoundSignal_callback                   qqmlboundsignal.cpp          358  0x7ffff718bf53 
          14  QQmlNotifier::emitNotify                   qqmlnotifier.cpp             106  0x7ffff71c9cf4 
          15  QQmlData::signalEmitted                    qqmlengine.cpp               880  0x7ffff716e274 
          16  QMetaObject::activate                      qobject.cpp                  3648 0x7ffff6a20c92 
          17  QQuickAbstractButtonPrivate::handleRelease qquickabstractbutton.cpp     179  0x7fffd0d71ca8 
          18  QQuickControl::mouseReleaseEvent           qquickcontrol.cpp            2099 0x7fffd0d8c9f5 
          19  QQuickItem::event                          qquickitem.cpp               8096 0x7fffd22c98de 
          20  QCoreApplication::notifyInternal2          qcoreapplication.cpp         1061 0x7ffff69f4c18         
          
          --> 2 <--
          
          1   QV4::IdentifierHash::lookup         qv4identifier.cpp            173  0x7ffff7058c28 
          2   QV4::IdentifierHash::value          qv4identifier_p.h            165  0x7ffff70a6bc5 
          3   QV4::QQmlContextWrapper::virtualGet qv4qmlcontext.cpp            196  0x7ffff70a6bc5 
          4   QV4::Object::get                    qv4object_p.h                314  0x7ffff7055b65 
          5   QV4::ExecutionContext::getProperty  qv4context.cpp               360  0x7ffff7055b65 
          6   QV4::Runtime::method_loadName       qv4runtime.cpp               985  0x7ffff7143df0 
          7   QV4::Moth::VME::interpret           qv4vme_moth.cpp              548  0x7ffff70e413e 
          8   QV4::Moth::VME::exec                qv4vme_moth.cpp              441  0x7ffff70e7cc4 
          9   QV4::ArrowFunction::virtualCall     qv4functionobject.cpp        513  0x7ffff7080720 
          10  QV4::FunctionObject::call           qv4functionobject_p.h        202  0x7ffff71474a3 
          11  QV4::Runtime::method_callName       qv4runtime.cpp               1346 0x7ffff71474a3 
          12  QV4::Moth::VME::interpret           qv4vme_moth.cpp              745  0x7ffff70e3e37 
          13  QV4::Moth::VME::exec                qv4vme_moth.cpp              441  0x7ffff70e7cc4 
          14  QV4::Function::call                 qv4function.cpp              68   0x7ffff707fade 
          15  QQmlJavaScriptExpression::evaluate  qqmljavascriptexpression.cpp 216  0x7ffff71e7eb8 
          16  QQmlBoundSignalExpression::evaluate qqmlboundsignal.cpp          225  0x7ffff718aa52 
          17  QQmlBoundSignal_callback            qqmlboundsignal.cpp          358  0x7ffff718bf53 
          18  QQmlNotifier::emitNotify            qqmlnotifier.cpp             106  0x7ffff71c9cf4 
          19  QQmlData::signalEmitted             qqmlengine.cpp               880  0x7ffff716e274 
          20  QMetaObject::activate               qobject.cpp                  3648 0x7ffff6a20c92 
          
          --> 3 <--
          
          1  QV4::Heap::String::append                        qv4string.cpp                235  0x7ffff714dcdc 
          2  QV4::Heap::String::simplifyString                qv4string.cpp                184  0x7ffff714de22 
          3  QV4::String::createPropertyKeyImpl               qv4string.cpp                172  0x7ffff714dfcb 
          4  QV4::StringOrSymbol::createPropertyKey           qv4string_p.h                311  0x7ffff714c324 
          5  QV4::StringOrSymbol::toPropertyKey               qv4string_p.h                316  0x7ffff714c324 
          6  QV4::Object::get                                 qv4object_p.h                308  0x7ffff714c324 
          7  QV4::Runtime::method_callProperty                qv4runtime.cpp               1376 0x7ffff714c324 
          8  QV4::Moth::VME::interpret                        qv4vme_moth.cpp              718  0x7ffff70e3f90 
          9  QV4::Moth::VME::exec                             qv4vme_moth.cpp              441  0x7ffff70e7cc4 
          10 QV4::ArrowFunction::virtualCall                  qv4functionobject.cpp        513  0x7ffff7080720 
          11 QV4::FunctionObject::call                        qv4functionobject_p.h        202  0x7ffff71474a3 
          12 QV4::Runtime::method_callName                    qv4runtime.cpp               1346 0x7ffff71474a3 
          13 QV4::Moth::VME::interpret                        qv4vme_moth.cpp              745  0x7ffff70e3e37 
          14 QV4::Moth::VME::exec                             qv4vme_moth.cpp              441  0x7ffff70e7cc4 
          15 QV4::Function::call                              qv4function.cpp              68   0x7ffff707fade 
          16 QQmlJavaScriptExpression::evaluate               qqmljavascriptexpression.cpp 216  0x7ffff71e7eb8 
          17 QQmlBoundSignalExpression::evaluate              qqmlboundsignal.cpp          225  0x7ffff718aa52 
          18 QQmlBoundSignal_callback                         qqmlboundsignal.cpp          358  0x7ffff718bf53 
          19 QQmlNotifier::emitNotify                         qqmlnotifier.cpp             106  0x7ffff71c9cf4 
          20 QQmlData::signalEmitted                          qqmlengine.cpp               880  0x7ffff716e274 
          21 QMetaObject::activate                            qobject.cpp                  3648 0x7ffff6a20c92 
          22 QQuickAbstractButtonPrivate::handleRelease       qquickabstractbutton.cpp     179  0x7fffd0d71ca8 
          23 QQuickControl::mouseReleaseEvent                 qquickcontrol.cpp            2099 0x7fffd0d8c9f5 
          24 QQuickItem::event                                qquickitem.cpp               8096 0x7fffd22c98de 
          25 QCoreApplication::notifyInternal2                qcoreapplication.cpp         1061 0x7ffff69f4c18 
          26 QCoreApplication::sendEvent                      qcoreapplication.cpp         1451 0x7ffff69f4dce 
          27 QQuickWindowPrivate::deliverMouseEvent           qquickwindow.cpp             1784 0x7fffd22e23bf 
          28 QQuickWindowPrivate::deliverPointerEvent         qquickwindow.cpp             2346 0x7fffd22e36fb 
          29 QQuickWindowPrivate::handleMouseEvent            qquickwindow.cpp             2210 0x7fffd22e4535 
          30 QWindow::event                                   qwindow.cpp                  2336 0x7ffff77044eb 
          31 QQuickWindow::event                              qquickwindow.cpp             1673 0x7fffd22e54e5 
          32 QCoreApplication::notifyInternal2                qcoreapplication.cpp         1061 0x7ffff69f4c18 
          33 QCoreApplication::sendSpontaneousEvent           qcoreapplication.cpp         1463 0x7ffff69f4dde 
          34 QGuiApplicationPrivate::processMouseEvent        qguiapplication.cpp          2102 0x7ffff76f91e7 
          35 QGuiApplicationPrivate::processWindowSystemEvent qguiapplication.cpp          1837 0x7ffff76fa795 
          36 QWindowSystemInterface::sendWindowSystemEvents   qwindowsysteminterface.cpp   1068 0x7ffff76d644b 
          37 xcbSourceDispatch                                qxcbeventdispatcher.cpp      105  0x7ffff014767a 
          38 g_main_context_dispatch                                                            0x7ffff24dc417 
          39 ??                                                                                 0x7ffff24dc650 
          40 g_main_context_iteration                                                           0x7ffff24dc6dc 
          41 QEventDispatcherGlib::processEvents              qeventdispatcher_glib.cpp    422  0x7ffff6a4bdcf 
          42 QEventLoop::exec                                 qeventloop.cpp               225  0x7ffff69f357a 
          43 QCoreApplication::exec                           qcoreapplication.cpp         1364 0x7ffff69fbf80 
          44 main                                             main.cpp                     28   0x55555555be66 
          
          --> 4 <--
          
          
          1  QV4::Object::get                                                                                                                          qv4object_p.h             310  0x7ffff713cee4 
          2  objectToVariant                                                                                                                           qv4engine.cpp             1389 0x7ffff713cee4 
          3  toVariant                                                                                                                                 qv4engine.cpp             1359 0x7ffff713d949 
          4  QV4::ExecutionEngine::toVariant                                                                                                           qv4engine.cpp             1252 0x7ffff713dc10 
          5  QJSValue::toVariant                                                                                                                       qjsvalue.cpp              714  0x7ffff70521e4 
          6  convertJSValueToVariantType<QList<QVariant>>                                                                                              qv8engine.cpp             100  0x7ffff721b4c1 
          7  QtPrivate::ConverterFunctor<QJSValue, QList<QVariant>, QList<QVariant> ( *)(QJSValue const&)>::convert                                    qmetatype.h               398  0x7ffff721b162 
          8  QMetaType::convert                                                                                                                        qmetatype.cpp             739  0x7ffff6a0b36d 
          9  (anonymous namespace)::convert                                                                                                            qvariant.cpp              393  0x7ffff6a3ada1 
          10 QtPrivate::QVariantValueHelper<QList<QVariant>>::metaType                                                                                 qvariant.h                725  0x55555555a42e 
          11 QtPrivate::MetaTypeInvoker<QtPrivate::QVariantValueHelper<QList<QVariant>>, QVariant const&, QList<QVariant>>::invoke                     qvariant.h                115  0x5555555594c7 
          12 QtPrivate::QVariantValueHelperInterface<QList<QVariant>>::invoke                                                                          qvariant.h                793  0x5555555589f0 
          13 qvariant_cast<QList<QVariant>>                                                                                                            qvariant.h                860  0x55555555a536 
          14 QVariant::value<QList<QVariant>>                                                                                                          qvariant.h                362  0x555555559576 
          15 Contractor::executeTask                                                                                                                   Contractor.cpp            44   0x555555557a9a 
          16 QtPrivate::FunctorCall<QtPrivate::IndexesList<0>, QtPrivate::List<ContractorTask *>, void, void (Contractor:: *)(ContractorTask *)>::call qobjectdefs_impl.h        152  0x55555555e49b 
          17 QtPrivate::FunctionPointer<void (Contractor:: *)(ContractorTask *)>::call<QtPrivate::List<ContractorTask *>, void>                        qobjectdefs_impl.h        185  0x55555555e179 
          18 QtPrivate::QSlotObject<void (Contractor:: *)(ContractorTask *), QtPrivate::List<ContractorTask *>, void>::impl                            qobjectdefs_impl.h        414  0x55555555de01 
          19 QObject::event                                                                                                                            qobject.cpp               1249 0x7ffff6a21581 
          20 QCoreApplication::notifyInternal2                                                                                                         qcoreapplication.cpp      1061 0x7ffff69f4c18 
          21 QCoreApplication::sendEvent                                                                                                               qcoreapplication.cpp      1451 0x7ffff69f4dce 
          22 QCoreApplicationPrivate::sendPostedEvents                                                                                                 qcoreapplication.cpp      1800 0x7ffff69f7647 
          23 QCoreApplication::sendPostedEvents                                                                                                        qcoreapplication.cpp      1654 0x7ffff69f7b28 
          24 postEventSourceDispatch                                                                                                                   qeventdispatcher_glib.cpp 276  0x7ffff6a4c793 
          25 g_main_context_dispatch                                                                                                                                                  0x7ffff24dc417 
          26 ??                                                                                                                                                                       0x7ffff24dc650 
          27 g_main_context_iteration                                                                                                                                                 0x7ffff24dc6dc 
          28 QEventDispatcherGlib::processEvents                                                                                                       qeventdispatcher_glib.cpp 422  0x7ffff6a4bdcf 
          29 QEventLoop::exec                                                                                                                          qeventloop.cpp            225  0x7ffff69f357a 
          30 QThread::exec                                                                                                                             qthread.cpp               531  0x7ffff682b7dc 
          31 QThreadPrivate::start                                                                                                                     qthread_unix.cpp          361  0x7ffff682cd13 
          32 start_thread                                                                                                                              pthread_create.c          463  0x7ffff5bdd6db 
          33 clone                                                                                                                                     clone.S                   95   0x7ffff5f1688f                                            
          
          --> 5 <--
          
          1   QV4::Object::ownPropertyKeys                                                                                                              qv4object_p.h         367  0x7ffff713cbdd 
          2   QV4::ObjectIterator::ObjectIterator                                                                                                       qv4objectiterator_p.h 80   0x7ffff713cbdd 
          3   objectToVariant                                                                                                                           qv4engine.cpp         1397 0x7ffff713cbdd 
          4   toVariant                                                                                                                                 qv4engine.cpp         1359 0x7ffff713d949 
          5   QV4::ExecutionEngine::toVariant                                                                                                           qv4engine.cpp         1252 0x7ffff713dc10 
          6   QJSValue::toVariant                                                                                                                       qjsvalue.cpp          714  0x7ffff70521e4 
          7   convertJSValueToVariantType<QList<QVariant>>                                                                                              qv8engine.cpp         100  0x7ffff721b4c1 
          8   QtPrivate::ConverterFunctor<QJSValue, QList<QVariant>, QList<QVariant> ( *)(QJSValue const&)>::convert                                    qmetatype.h           398  0x7ffff721b162 
          9   QMetaType::convert                                                                                                                        qmetatype.cpp         739  0x7ffff6a0b36d 
          10  (anonymous namespace)::convert                                                                                                            qvariant.cpp          393  0x7ffff6a3ada1 
          11  QtPrivate::QVariantValueHelper<QList<QVariant>>::metaType                                                                                 qvariant.h            725  0x55555555a42e 
          12  QtPrivate::MetaTypeInvoker<QtPrivate::QVariantValueHelper<QList<QVariant>>, QVariant const&, QList<QVariant>>::invoke                     qvariant.h            115  0x5555555594c7 
          13  QtPrivate::QVariantValueHelperInterface<QList<QVariant>>::invoke                                                                          qvariant.h            793  0x5555555589f0 
          14  qvariant_cast<QList<QVariant>>                                                                                                            qvariant.h            860  0x55555555a536 
          15  QVariant::value<QList<QVariant>>                                                                                                          qvariant.h            362  0x555555559576 
          16  Contractor::executeTask                                                                                                                   Contractor.cpp        44   0x555555557a9a 
          17  QtPrivate::FunctorCall<QtPrivate::IndexesList<0>, QtPrivate::List<ContractorTask *>, void, void (Contractor:: *)(ContractorTask *)>::call qobjectdefs_impl.h    152  0x55555555e49b 
          18  QtPrivate::FunctionPointer<void (Contractor:: *)(ContractorTask *)>::call<QtPrivate::List<ContractorTask *>, void>                        qobjectdefs_impl.h    185  0x55555555e179 
          19  QtPrivate::QSlotObject<void (Contractor:: *)(ContractorTask *), QtPrivate::List<ContractorTask *>, void>::impl                            qobjectdefs_impl.h    414  0x55555555de01 
          20  QObject::event                                                                                                                            qobject.cpp           1249 0x7ffff6a21581 
          ... <More>                                                                                                                                                                              
          
          --> 6 <--
          
          1   QV4::Heap::String::append                  qv4string.cpp         235  0x7ffff714dcdc 
          2   QV4::Heap::String::simplifyString          qv4string.cpp         184  0x7ffff714de22 
          3   QV4::Heap::StringOrSymbol::createHashValue qv4string.cpp         245  0x7ffff714e185 
          4   QV4::Heap::StringOrSymbol::hashValue       qv4string_p.h         97   0x7ffff70ceb35 
          5   QV4::Heap::String::isEqualTo               qv4string_p.h         128  0x7ffff70ceb35 
          6   QV4::String::equals                        qv4string_p.h         203  0x7ffff70cb3db 
          7   QV4::QObjectWrapper::getQmlProperty        qv4qobjectwrapper.cpp 283  0x7ffff70cb3db 
          8   QV4::QObjectWrapper::getQmlProperty        qv4qobjectwrapper.cpp 414  0x7ffff70cbc4e 
          9   QV4::QQmlContextWrapper::virtualGet        qv4qmlcontext.cpp     246  0x7ffff70a6c66 
          10  QV4::Object::get                           qv4object_p.h         314  0x7ffff7055b65 
          11  QV4::ExecutionContext::getProperty         qv4context.cpp        360  0x7ffff7055b65 
          12  QV4::Runtime::method_loadName              qv4runtime.cpp        985  0x7ffff7143df0 
          13  QV4::Moth::VME::interpret                  qv4vme_moth.cpp       548  0x7ffff70e413e 
          14  QV4::Moth::VME::exec                       qv4vme_moth.cpp       441  0x7ffff70e7cc4 
          15  QV4::ArrowFunction::virtualCall            qv4functionobject.cpp 513  0x7ffff7080720 
          16  QV4::FunctionObject::call                  qv4functionobject_p.h 202  0x7ffff71474a3 
          17  QV4::Runtime::method_callName              qv4runtime.cpp        1346 0x7ffff71474a3 
          18  QV4::Moth::VME::interpret                  qv4vme_moth.cpp       745  0x7ffff70e3e37 
          19  QV4::Moth::VME::exec                       qv4vme_moth.cpp       441  0x7ffff70e7cc4 
          20  QV4::Function::call                        qv4function.cpp       68   0x7ffff707fade 
          ... <More>                                                                               
          
          
          kshegunovK Offline
          kshegunovK Offline
          kshegunov
          Moderators
          wrote on 21 May 2019, 19:13 last edited by
          #6

          @Matthew11 said in Passing custom type pointers between threads via signals and slots cause app to crash:

          So, If I understand it correctly, it gives me insights where and when another thread is working on resources from another thread?

          Indeed.

          So it happens when Contractor is working on _task in Contractor::executeTask(ContractorTask*) which is "normal" in this case. And these places should be protected. Am I right, that's the hint?

          Yes, although I'm not quite convinced you're going to manage that really gracefully. Why isn't the task something which belongs to a specific thread (i.e. moved to and operated on) by a single thread?

          Returning to stack traces, I generated them for the same code included before. App crashes seem to be connected with QV4Object. 3'rd and 6'th seem to be more common.

          Look down. These come from QML, there're calls into your objects that originate from different threads. I imagine that's because the Task has no notion of ownership. I'm not much into QML but it seems you get your code called from different threads, which is a bad idea.

          Is the table content enough or will it be better with screenshots?

          It's fine.

          Read and abide by the Qt Code of Conduct

          M 1 Reply Last reply 22 May 2019, 08:00
          3
          • kshegunovK kshegunov
            21 May 2019, 19:13

            @Matthew11 said in Passing custom type pointers between threads via signals and slots cause app to crash:

            So, If I understand it correctly, it gives me insights where and when another thread is working on resources from another thread?

            Indeed.

            So it happens when Contractor is working on _task in Contractor::executeTask(ContractorTask*) which is "normal" in this case. And these places should be protected. Am I right, that's the hint?

            Yes, although I'm not quite convinced you're going to manage that really gracefully. Why isn't the task something which belongs to a specific thread (i.e. moved to and operated on) by a single thread?

            Returning to stack traces, I generated them for the same code included before. App crashes seem to be connected with QV4Object. 3'rd and 6'th seem to be more common.

            Look down. These come from QML, there're calls into your objects that originate from different threads. I imagine that's because the Task has no notion of ownership. I'm not much into QML but it seems you get your code called from different threads, which is a bad idea.

            Is the table content enough or will it be better with screenshots?

            It's fine.

            M Offline
            M Offline
            Matthew11
            wrote on 22 May 2019, 08:00 last edited by
            #7

            @kshegunov said in Passing custom type pointers between threads via signals and slots cause app to crash:

            Yes, although I'm not quite convinced you're going to manage that really gracefully.

            This is why when I adopted mutexes in Contractor::executeTask(ContractorTask*) or inside ContractorTask it's still crashing? Or maybe it wasn't done well by me?

            @kshegunov said in Passing custom type pointers between threads via signals and slots cause app to crash:

            Why isn't the task something which belongs to a specific thread (i.e. moved to and operated on) by a single thread?

            So, when ContractorTask is shared (and called from different threads), it dramatically cut down the number of connections via threads and QML but also makes it vulnerable. And by using QVariant I can put there various data types from standard types to custom types, which I need in order to present user or send user input to the worker (and then further) which also cut down the number of connect's. And yeah, (correct me if I am wrong) I can do this with countable numbers of signals/slots passing different parameters with QueuedConnection and passing the data by value which is a (AFAIK) safe solution. But firstly I would like to give a try with using the sharaed resource and make it safe.

            J 1 Reply Last reply 22 May 2019, 08:14
            0
            • M Matthew11
              22 May 2019, 08:00

              @kshegunov said in Passing custom type pointers between threads via signals and slots cause app to crash:

              Yes, although I'm not quite convinced you're going to manage that really gracefully.

              This is why when I adopted mutexes in Contractor::executeTask(ContractorTask*) or inside ContractorTask it's still crashing? Or maybe it wasn't done well by me?

              @kshegunov said in Passing custom type pointers between threads via signals and slots cause app to crash:

              Why isn't the task something which belongs to a specific thread (i.e. moved to and operated on) by a single thread?

              So, when ContractorTask is shared (and called from different threads), it dramatically cut down the number of connections via threads and QML but also makes it vulnerable. And by using QVariant I can put there various data types from standard types to custom types, which I need in order to present user or send user input to the worker (and then further) which also cut down the number of connect's. And yeah, (correct me if I am wrong) I can do this with countable numbers of signals/slots passing different parameters with QueuedConnection and passing the data by value which is a (AFAIK) safe solution. But firstly I would like to give a try with using the sharaed resource and make it safe.

              J Offline
              J Offline
              J.Hilk
              Moderators
              wrote on 22 May 2019, 08:14 last edited by
              #8

              @Matthew11
              are you by any chance exposing those thread-shared custom types directly to qml?

              If yes, then that is a bad idea and my very well be the reason for your issues.


              Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


              Q: What's that?
              A: It's blue light.
              Q: What does it do?
              A: It turns blue.

              M 1 Reply Last reply 22 May 2019, 08:39
              3
              • J J.Hilk
                22 May 2019, 08:14

                @Matthew11
                are you by any chance exposing those thread-shared custom types directly to qml?

                If yes, then that is a bad idea and my very well be the reason for your issues.

                M Offline
                M Offline
                Matthew11
                wrote on 22 May 2019, 08:39 last edited by Matthew11
                #9

                @J.Hilk said in Passing custom type pointers between threads via signals and slots cause app to crash:

                @Matthew11 are you by any chance exposing those thread-shared custom types directly to qml?

                If yes, then that is a bad idea and my very well be the reason for your issues.

                Unfortunately yes, and it actually happening:

                // main.cpp:
                engine.rootContext()->setContextProperty("Task", &Task);
                

                And in QML I am working directly on that shared resources:

                // main.qml:
                Task.setTaskID(_taskId)
                Task.setContractorID(
                TaskController.startTask(Task)
                

                OK, that's the good clue. Could you tell more why is that? Is it connected with JS / qml engine stuff?

                J 1 Reply Last reply 22 May 2019, 08:52
                0
                • M Matthew11
                  22 May 2019, 08:39

                  @J.Hilk said in Passing custom type pointers between threads via signals and slots cause app to crash:

                  @Matthew11 are you by any chance exposing those thread-shared custom types directly to qml?

                  If yes, then that is a bad idea and my very well be the reason for your issues.

                  Unfortunately yes, and it actually happening:

                  // main.cpp:
                  engine.rootContext()->setContextProperty("Task", &Task);
                  

                  And in QML I am working directly on that shared resources:

                  // main.qml:
                  Task.setTaskID(_taskId)
                  Task.setContractorID(
                  TaskController.startTask(Task)
                  

                  OK, that's the good clue. Could you tell more why is that? Is it connected with JS / qml engine stuff?

                  J Offline
                  J Offline
                  J.Hilk
                  Moderators
                  wrote on 22 May 2019, 08:52 last edited by
                  #10

                  @Matthew11
                  you should probably wrap that in manager class instead.

                  Could you tell more why is that? Is it connected with JS / qml engine stuff

                  most likely. I don't know enough about the inner workings to give you a definite answer. I can only tell you that I always ran into trouble when I tried to access/manipulate c++ threaded stuff (directly)via QML.

                  Since than I always have a manger object that forwards stuff via signals or from its own memory when exposed directly.


                  Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                  Q: What's that?
                  A: It's blue light.
                  Q: What does it do?
                  A: It turns blue.

                  M 1 Reply Last reply 22 May 2019, 09:07
                  1
                  • J J.Hilk
                    22 May 2019, 08:52

                    @Matthew11
                    you should probably wrap that in manager class instead.

                    Could you tell more why is that? Is it connected with JS / qml engine stuff

                    most likely. I don't know enough about the inner workings to give you a definite answer. I can only tell you that I always ran into trouble when I tried to access/manipulate c++ threaded stuff (directly)via QML.

                    Since than I always have a manger object that forwards stuff via signals or from its own memory when exposed directly.

                    M Offline
                    M Offline
                    Matthew11
                    wrote on 22 May 2019, 09:07 last edited by Matthew11
                    #11

                    @J.Hilk said in Passing custom type pointers between threads via signals and slots cause app to crash:

                    you should probably wrap that in manager class instead.
                    Since than I always have a manger object that forwards stuff via signals or from its own memory when exposed directly.

                    I was going to do it like this.

                    Let's clarify some aspects of your approach.

                    1. Manager <-> Threads :
                    • communicate via signal/slots with QueuedConnection
                    • synchronization/locking on the shared resource

                    @J.Hilk said in Passing custom type pointers between threads via signals and slots cause app to crash:

                    manger object that forwards stuff via signals or from its own memory when exposed directly.

                    1. Manager <-> QML
                    • signals and slots
                    • or directly from manager's memory

                    Have I figured it out properly?

                    J 1 Reply Last reply 23 May 2019, 05:17
                    0
                    • M Matthew11
                      22 May 2019, 09:07

                      @J.Hilk said in Passing custom type pointers between threads via signals and slots cause app to crash:

                      you should probably wrap that in manager class instead.
                      Since than I always have a manger object that forwards stuff via signals or from its own memory when exposed directly.

                      I was going to do it like this.

                      Let's clarify some aspects of your approach.

                      1. Manager <-> Threads :
                      • communicate via signal/slots with QueuedConnection
                      • synchronization/locking on the shared resource

                      @J.Hilk said in Passing custom type pointers between threads via signals and slots cause app to crash:

                      manger object that forwards stuff via signals or from its own memory when exposed directly.

                      1. Manager <-> QML
                      • signals and slots
                      • or directly from manager's memory

                      Have I figured it out properly?

                      J Offline
                      J Offline
                      J.Hilk
                      Moderators
                      wrote on 23 May 2019, 05:17 last edited by
                      #12

                      @Matthew11
                      jep, pretty much.
                      That at least is how I (would)do it.


                      Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                      Q: What's that?
                      A: It's blue light.
                      Q: What does it do?
                      A: It turns blue.

                      1 Reply Last reply
                      2
                      • M Offline
                        M Offline
                        Matthew11
                        wrote on 25 May 2019, 20:02 last edited by Matthew11
                        #13

                        OK as @J.Hilk said:

                        @J.Hilk said in Passing custom type pointers between threads via signals and slots cause app to crash:

                        are you by any chance exposing those thread-shared custom types directly to qml?

                        And:

                        @J.Hilk said in Passing custom type pointers between QML and threads via signals and slots cause app to crash:

                        I can only tell you that I always ran into trouble when I tried to access/manipulate c++ threaded stuff (directly)via QML.

                        Indeed that was causing the crashes. The solution is to create a copy of the resource that is sent from QML and then send a copy of that resource to thread.

                        As @J.Hilk suggested Manager object should do the job which is:

                        @Matthew11 said in [Passing custom type pointers between QML and threads via signals and slots cause app to crash

                        1. Manager <-> Threads :
                        • communicate via signal/slots with QueuedConnection
                        • synchronization/locking on the shared resource
                        1. Manager <-> QML
                        • signals and slots
                        • or directly from the manager's memory

                        Below you can find my working example. This is very similar to the code which I provided in the first post. You send a dispatch from QML to specific Contractor, Contractor then is doing his job and return the result back to QML (sends task with input data scenario). Or you send a dispatch to Contractor to retrieve some data (send task with no input data scenario). ContractorTask is no longer exposed to QML. But pointers are no longer send however it is possible in the C++ domain (across main (Manager) and workers threads with proper locking/synchronization).

                        If you want to feel how it is when app is crashing uncomment the line _taskCopy.setData(_data); from pushTaskToContractor() in Controller.h which disabling the step of making the copy of the resource.

                        Thank you all for your help in solving the problem!

                        Code:

                        //.pro
                        
                        QT += quick
                        CONFIG += c++11
                        
                        SOURCES += \
                                Contractor.cpp \
                                main.cpp
                        
                        RESOURCES += qml.qrc
                        
                        HEADERS += \
                            Contractor.h \
                            ContractorTask.h \
                            Controller.h
                        
                        // Contractor.h
                        
                        #ifndef CONTRACTOR_H
                        #define CONTRACTOR_H
                        
                        #include <QObject>
                        
                        #include <ContractorTask.h>
                        
                        class Contractor : public QObject
                        {
                            Q_OBJECT
                        
                        public:
                            Contractor(int _ID, QObject* parent = nullptr);
                        
                            int getID() { return ID; }
                        
                        public slots:
                            void executeTask(ContractorTask _task);
                        
                        signals:
                            void finished();
                            void taskStarted(ContractorTask _task);
                            void taskFinished(ContractorTask _task);
                        
                        private:
                            int ID;
                        };
                        
                        #endif // CONTRACTOR_H
                        
                        // Contractor.cpp
                        
                        #include "Contractor.h"
                        
                        #include <QDebug>
                        #include <QThread>
                        
                        Contractor::Contractor(int _ID, QObject *parent) :
                            QObject(parent),
                            ID(_ID)
                        {}
                        
                        void Contractor::executeTask(ContractorTask _task)
                        {
                            emit(taskStarted(_task));
                        
                            if(getID() != _task.getConctractorID())
                            {
                                qDebug() << "Not mine ID, discarding";
                                return;
                            }
                        
                            QVariant localData = _task.getData();
                        
                            switch(_task.getTaskID())
                            {
                            case 0: // PASS TASK TO C++ TO RETRIEVE DATA
                            {
                                QList<QVariant> _params;
                                _params.append(12.5F);
                                _params.append(14.36F);
                        
                                QVariant _data = _params;
                        
                                _task.setData(_data);
                        
                                qDebug() << "PASS TASK TO C++ TO RETRIEVE DATA";
                            }
                                break;
                            case 1: // PASS TASK WITH DATA TO C++ AND GET THE SAME DATA BACK IN QML
                            {
                                QList<QVariant> _params;
                                _params = localData.value<QList<QVariant>>();
                        
                                QList<float> _floats;
                                int counter = 0;
                                for(auto item : _params)
                                {
                                    _floats << item.toFloat();
                                    qDebug() << "Getting data in C++ from QML (QList<float>): item =" << counter++ << "value =" << item;
                                }
                        
                                qDebug() << "PASS TASK WITH DATA TO C++ AND GET THE SAME DATA BACK IN QML";
                            }
                                break;
                            default:
                            {
                                qDebug() << "Oh... I don't have these one :(";
                            }
                            }
                        
                            emit(taskFinished(_task));
                        }
                        
                        // ContractorTask.h
                        
                        #ifndef CONTRACTORTASK_H
                        #define CONTRACTORTASK_H
                        
                        #include <QVariant>
                        
                        class ContractorTask
                        {
                        public:
                            ContractorTask() :
                                taskID(-1),
                                contractorID(-1),
                                data("")
                            {}
                        
                            int getTaskID() { return taskID; }
                        
                            void setTaskID(int _ID) {taskID = _ID; }
                        
                            int getConctractorID() { return contractorID; }
                        
                            void setContractorID(int _ID) { contractorID = _ID; }
                        
                            QVariant getData() { return data; }
                        
                            void setData(QVariant _data) { data = _data; }
                        
                        private:
                            int taskID;
                            int contractorID;
                            QVariant data;
                        };
                        
                        Q_DECLARE_METATYPE(ContractorTask)
                        
                        #endif // CONTRACTORTASK_H
                        
                        
                        // Controller.h
                        
                        #ifndef CONTROLLER
                        #define CONTROLLER
                        
                        #include <QObject>
                        #include <QThread>
                        #include <QDebug>
                        
                        #include <Contractor.h>
                        #include <ContractorTask.h>
                        
                        class Controller : public QObject
                        {
                            Q_OBJECT
                            QThread workerThread;
                        public:
                            Controller()
                            {
                                Contractor *worker = new Contractor(0);
                                worker->moveToThread(&workerThread);
                        
                                connect(&workerThread, &QThread::finished, worker, &QObject::deleteLater);
                        
                                connect(this, &Controller::startTask, worker, &Contractor::executeTask);
                                connect(worker, &Contractor::taskStarted, this, &Controller::contractorStartedTask);
                                connect(worker, &Contractor::taskFinished, this, &Controller::contractorFinishedTask);
                                workerThread.start();
                            }
                        
                            ~Controller()
                            {
                                workerThread.quit();
                                workerThread.wait();
                            }
                        
                        signals:
                            void startTask(ContractorTask);
                            void taskStarted(int id, int contractor, QVariant data);
                            void taskEnded(int id, int contractor, QVariant data);
                        
                        public slots:
                            void pushTaskToContractor(int _id, int _contractor, QVariant _data)
                            {
                                // QVariant depends to QML, so make COPY of QVariant CONTENT, before passing it to thread:
                                QList<QVariant> _params;
                                _params = _data.value<QList<QVariant>>();
                                QVariant _dataToSend = _params;
                        
                                ContractorTask _taskCopy;
                                _taskCopy.setTaskID(_id);
                                _taskCopy.setContractorID(_contractor);
                                _taskCopy.setData(_dataToSend);                 // Sending local data copy is OK
                        
                        //        _taskCopy.setData(_data);                     // Sending _data (has source in QML) = PROGRAM CRASH!!!
                        
                                emit(startTask(_taskCopy));
                            }
                        
                            void contractorFinishedTask(ContractorTask _task)
                            {
                                // Passing COPY of ContractorTask to QML:
                                emit(taskEnded(_task.getTaskID(), _task.getConctractorID(), _task.getData()));
                            }
                        
                            void contractorStartedTask(ContractorTask _task)
                            {
                                // Passing COPY of ContractorTask to QML:
                                emit(taskStarted(_task.getTaskID(), _task.getConctractorID(), _task.getData()));
                            }
                        };
                        
                        #endif // CONTROLLER
                        
                        // main.cpp
                        
                        #include <QGuiApplication>
                        #include <QQmlApplicationEngine>
                        #include <Controller.h>
                        #include <QQmlContext>
                        
                        int main(int argc, char *argv[])
                        {
                            QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
                        
                            QGuiApplication app(argc, argv);
                        
                            Controller TaskController;
                            qRegisterMetaType<ContractorTask>();
                        
                            QQmlApplicationEngine engine;
                            engine.rootContext()->setContextProperty("TaskController", &TaskController);
                        
                            const QUrl url(QStringLiteral("qrc:/main.qml"));
                            QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
                                             &app, [url](QObject *obj, const QUrl &objUrl) {
                                if (!obj && url == objUrl)
                                    QCoreApplication::exit(-1);
                            }, Qt::QueuedConnection);
                            engine.load(url);
                        
                        
                            // Get item from QML, and connect it's signal (startTaskFromQML) to Controller
                            QObject *item = engine.rootObjects().first();
                            QObject::connect(item, SIGNAL(startTaskFromQML(int, int, QVariant)),
                                             &TaskController, SLOT(pushTaskToContractor(int, int, QVariant)));
                        
                        
                            return app.exec();
                        }
                        
                        // main.qml
                        
                        import QtQuick 2.12
                        import QtQuick.Controls 2.5
                        
                        ApplicationWindow {
                            id: root
                            visible: true
                            width: 640
                            height: 480
                            title: qsTr("Test")
                        
                            signal startTaskFromQML(int id, int contractor, variant data)
                            property variant _data: 0
                        
                            Connections {
                                target: TaskController
                        
                                onTaskEnded: console.log("Contractor with ID =", contractor, "finished task with ID = ", id, "and returned result:", data);
                        
                                onTaskStarted: console.log("Contractor with ID =", contractor, "started task with ID = ", id);
                            }
                        
                            Column {
                                id: column
                                anchors.horizontalCenter: parent.horizontalCenter
                                anchors.verticalCenter: parent.verticalCenter
                                Button {
                                    id: passAndGet
                                    text: qsTr("PASS TASK WITH DATA TO C++ AND GET THE SAME DATA BACK IN QML")
                                    anchors.horizontalCenter: parent.horizontalCenter
                        
                                    onClicked: {
                                        _data= [1.2, 3.4, 5.6, 7.8]
                        
                                        for(var i = 0; i < 50; i++)
                                        {
                                            root.startTaskFromQML(1, 0, _data)
                                        }
                                    }
                                }
                        
                                Button {
                                    id: getData
                                    text: qsTr("PASS TASK TO C++ TO RETRIEVE DATA")
                                    anchors.horizontalCenter: parent.horizontalCenter
                        
                                    onClicked: {
                                        _data = 0
                                        root.startTaskFromQML(0, 0, _data)
                                    }
                                }
                            }
                        }
                        
                        // qtquickcontrols2.conf
                        
                        [Controls]
                        Style=Material
                        
                        // qml.qrc
                        
                        <RCC>
                            <qresource prefix="/">
                                <file>main.qml</file>
                                <file>qtquickcontrols2.conf</file>
                            </qresource>
                        </RCC>
                        
                        1 Reply Last reply
                        2

                        12/13

                        23 May 2019, 05:17

                        • Login

                        • Login or register to search.
                        12 out of 13
                        • First post
                          12/13
                          Last post
                        0
                        • Categories
                        • Recent
                        • Tags
                        • Popular
                        • Users
                        • Groups
                        • Search
                        • Get Qt Extensions
                        • Unsolved