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. Randomly Occuring assertion error
Forum Updated to NodeBB v4.3 + New Features

Randomly Occuring assertion error

Scheduled Pinned Locked Moved Solved General and Desktop
10 Posts 4 Posters 925 Views 1 Watching
  • 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.
  • C Offline
    C Offline
    ChrisWeiter
    wrote on last edited by
    #1

    Hello everybody,

    I'm pretty new to qt and currently facing some strange behaviour of my program I can't explain to my self.
    The purpose of my code is to interface two sensor devices and forward the obtained information to a control loop. This is why i chose threads.

    Like every second time I run my the code (without compiling in the mean time), I get this error:
    ASSERT failure in QCoreApplication::sendEvent: "Cannot send events to objects owned by a different thread. Current thread 0x0x8501bb0. Receiver '' (of type 'QTimer') was created in thread 0x0x8670578", file kernel\qcoreapplication.cpp, line 576

    The code where all threads are defined and stuff looks like this:

        m_CommThread = new CCommRunnable(IpHandDevice,DeviceType::Hand);
        qDebug()<<"m_CommThread:"<<m_CommThread->thread();
        m_CommTimer = new QTimer();
        qDebug()<<"m_CommTimer"<<m_CommTimer->thread();
    
    
    
       m_CommThreadHead = new CCommRunnable(IpHeadDevice,DeviceType::Head);
       qDebug()<<"m_CommThreadHead"<<m_CommThreadHead->thread();
       m_CommHeadTimer = new QTimer();
       qDebug()<<"m_CommHeadTimer"<<m_CommHeadTimer->thread();
    
        m_ControlThread = new CControlRunnable();
        qDebug()<<"m_ControlThread"<<m_ControlThread->thread();
        m_ControlTimer = new QTimer();
        qDebug()<<"m_ControlTimer"<<m_ControlTimer->thread();
    
        m_CommTimer->setInterval(m_CommPeriod);
        m_CommHeadTimer->setInterval(m_CommPeriod);
        m_ControlTimer->setInterval(m_ControlPeriod);
    
        QObject::connect(m_CommTimer, &QTimer::timeout,m_CommThread,&CCommRunnable::onTimeOut);
        QObject::connect(m_CommHeadTimer, &QTimer::timeout,m_CommThreadHead,&CCommRunnable::onTimeOut);
        QObject::connect(m_ControlTimer, &QTimer::timeout,m_ControlThread,&CControlRunnable::onTimeOut);
    
        QObject::connect(m_CommThread, &CCommRunnable::sigNewValues,m_ControlThread,&CControlRunnable::sltOnNewValues);
    
        QThreadPool::globalInstance()->start(m_CommThread,0);
        QThreadPool::globalInstance()->start(m_CommThreadHead,0);
        QThreadPool::globalInstance()->start(m_ControlThread,0);
    
        m_CommTimer->start();
        m_CommHeadTimer->start();
        m_ControlTimer->start();
    

    Could someone explain this behaviour to me? I'd be glad to fix the error but also to get a understanding where it's coming from.

    Cheers,
    Chris

    1 Reply Last reply
    0
    • CKurduC Offline
      CKurduC Offline
      CKurdu
      wrote on last edited by
      #2

      Hi,
      Try to add a paramater Qt::QueuedConnection at all QObject::connect as below.

      QObject::connect(m_CommTimer, &QTimer::timeout,m_CommThread,&CCommRunnable::onTimeOut,  Qt::QueuedConnection );
      QObject::connect(m_CommHeadTimer, &QTimer::timeout,m_CommThreadHead,&CCommRunnable::onTimeOut, Qt::QueuedConnection );
      QObject::connect(m_ControlTimer, &QTimer::timeout,m_ControlThread,&CControlRunnable::onTimeOut, Qt::QueuedConnection );
      

      sendEvent works directly. PostEvent sends messages to Qt Message Queue.

      You reap what you sow it

      kshegunovK 1 Reply Last reply
      1
      • C Offline
        C Offline
        ChrisWeiter
        wrote on last edited by
        #3

        Thanks for the switft response, sadly it didn't fix the problem.

        I'm wondering if there are any background processes which are the cause of this problem.
        In my code I've never created a connection with the a QTimer as a reciever, but the error message points out that a qtimer is the reciever of this failing message. Current thread 0x0x8501bb0. Receiver '' (of type 'QTimer') was created in thread 0x0x8670578

        aha_1980A CKurduC 2 Replies Last reply
        0
        • C ChrisWeiter

          Thanks for the switft response, sadly it didn't fix the problem.

          I'm wondering if there are any background processes which are the cause of this problem.
          In my code I've never created a connection with the a QTimer as a reciever, but the error message points out that a qtimer is the reciever of this failing message. Current thread 0x0x8501bb0. Receiver '' (of type 'QTimer') was created in thread 0x0x8670578

          aha_1980A Offline
          aha_1980A Offline
          aha_1980
          Lifetime Qt Champion
          wrote on last edited by
          #4

          Hi @ChrisWeiter, welcome.

          You should read https://mayaposch.wordpress.com/2011/11/01/how-to-really-truly-use-qthreads-the-full-explanation if you really need threads for your task (which I doubt).

          Regards

          Qt has to stay free or it will die.

          1 Reply Last reply
          3
          • C ChrisWeiter

            Thanks for the switft response, sadly it didn't fix the problem.

            I'm wondering if there are any background processes which are the cause of this problem.
            In my code I've never created a connection with the a QTimer as a reciever, but the error message points out that a qtimer is the reciever of this failing message. Current thread 0x0x8501bb0. Receiver '' (of type 'QTimer') was created in thread 0x0x8670578

            CKurduC Offline
            CKurduC Offline
            CKurdu
            wrote on last edited by
            #5

            @ChrisWeiter

            It seems also QObject::connect is in the wrong place. I am not sure also your Runnables is correct. QObject::connect should be placed after the "QThreadPool::globalInstance()->start(m_ControlThread,0);". All of your Runnable slots should connect a worker class that should be created in your Runnable::run method and Runnable::run method should end an exec() to start event queue.

            Can you send your Runnable class. May be I can help correctly.

            You reap what you sow it

            C 1 Reply Last reply
            1
            • CKurduC CKurdu

              Hi,
              Try to add a paramater Qt::QueuedConnection at all QObject::connect as below.

              QObject::connect(m_CommTimer, &QTimer::timeout,m_CommThread,&CCommRunnable::onTimeOut,  Qt::QueuedConnection );
              QObject::connect(m_CommHeadTimer, &QTimer::timeout,m_CommThreadHead,&CCommRunnable::onTimeOut, Qt::QueuedConnection );
              QObject::connect(m_ControlTimer, &QTimer::timeout,m_ControlThread,&CControlRunnable::onTimeOut, Qt::QueuedConnection );
              

              sendEvent works directly. PostEvent sends messages to Qt Message Queue.

              kshegunovK Offline
              kshegunovK Offline
              kshegunov
              Moderators
              wrote on last edited by
              #6

              @CKurdu said in Randomly Occuring assertion error:

              Try to add a paramater Qt::QueuedConnection at all QObject::connect as below.

              Doing this semi-randomly is really bad advice. If a program doesn't work with auto connections it's a safe bet forcing queued isn't going to fix it. At best it's going to hide some problem.

              @ChrisWeiter said in Randomly Occuring assertion error:

              Could someone explain this behaviour to me?

              Not without enough information. For one what does the stack trace show? For two what are those classes that are being run in separate threads, and have you made sure they don't touch non-reentrant/non-thread-safe data?

              Also don't use threads if you don't need them (not clear here if you do or don't), you'll spare yourself a lot of headaches.

              Read and abide by the Qt Code of Conduct

              1 Reply Last reply
              3
              • CKurduC CKurdu

                @ChrisWeiter

                It seems also QObject::connect is in the wrong place. I am not sure also your Runnables is correct. QObject::connect should be placed after the "QThreadPool::globalInstance()->start(m_ControlThread,0);". All of your Runnable slots should connect a worker class that should be created in your Runnable::run method and Runnable::run method should end an exec() to start event queue.

                Can you send your Runnable class. May be I can help correctly.

                C Offline
                C Offline
                ChrisWeiter
                wrote on last edited by
                #7

                @CKurdu said in Randomly Occuring assertion error:

                @ChrisWeiter

                It seems also QObject::connect is in the wrong place. I am not sure also your Runnables is correct. QObject::connect should be placed after the "QThreadPool::globalInstance()->start(m_ControlThread,0);". All of your Runnable slots should connect a worker class that should be created in your Runnable::run method and Runnable::run method should end an exec() to start event queue.

                Can you send your Runnable class. May be I can help correctly.

                Thanks CKurdu. With your hints I was able to fix it.
                Because I ran into some difficulties earlier, I moved all the code from the run to the constructor.
                The solution was to initialize the worker in the constructor, but do the connections in the run().

                Below the working code.

                CCommRunnable::CCommRunnable(QString DeviceIp, DeviceType DeviceTypeIndicator)
                {
                    WorkerDataCollector = new CDataCollector(DeviceIp);
                }
                
                void CCommRunnable::run()
                {
                    QObject::connect(this,&CBasisRunnable::sigDoWork,WorkerDataCollector,
                        &CDataCollector::onDoWork,Qt::QueuedConnection);
                   QObject::connect(WorkerDataCollector,&CDataCollector::sigNewData,this,
                    &CCommRunnable::sltonValuesChanged,Qt::QueuedConnection);
                
                    m_EventLoop.exec(QEventLoop::AllEvents);
                }
                

                @kshegunov considering your comment on the connection, I'm going to remove the parameter.
                @aha_1980 why do you doubt I need threads? I'm not eager to use them, but as I interface the sensors via a socket connection it seemed best to me, to make the different parts of my code independent from the responsiveness of the connection. And probably there will be added more stuff to interface in the future.

                aha_1980A CKurduC 3 Replies Last reply
                0
                • C ChrisWeiter

                  @CKurdu said in Randomly Occuring assertion error:

                  @ChrisWeiter

                  It seems also QObject::connect is in the wrong place. I am not sure also your Runnables is correct. QObject::connect should be placed after the "QThreadPool::globalInstance()->start(m_ControlThread,0);". All of your Runnable slots should connect a worker class that should be created in your Runnable::run method and Runnable::run method should end an exec() to start event queue.

                  Can you send your Runnable class. May be I can help correctly.

                  Thanks CKurdu. With your hints I was able to fix it.
                  Because I ran into some difficulties earlier, I moved all the code from the run to the constructor.
                  The solution was to initialize the worker in the constructor, but do the connections in the run().

                  Below the working code.

                  CCommRunnable::CCommRunnable(QString DeviceIp, DeviceType DeviceTypeIndicator)
                  {
                      WorkerDataCollector = new CDataCollector(DeviceIp);
                  }
                  
                  void CCommRunnable::run()
                  {
                      QObject::connect(this,&CBasisRunnable::sigDoWork,WorkerDataCollector,
                          &CDataCollector::onDoWork,Qt::QueuedConnection);
                     QObject::connect(WorkerDataCollector,&CDataCollector::sigNewData,this,
                      &CCommRunnable::sltonValuesChanged,Qt::QueuedConnection);
                  
                      m_EventLoop.exec(QEventLoop::AllEvents);
                  }
                  

                  @kshegunov considering your comment on the connection, I'm going to remove the parameter.
                  @aha_1980 why do you doubt I need threads? I'm not eager to use them, but as I interface the sensors via a socket connection it seemed best to me, to make the different parts of my code independent from the responsiveness of the connection. And probably there will be added more stuff to interface in the future.

                  aha_1980A Offline
                  aha_1980A Offline
                  aha_1980
                  Lifetime Qt Champion
                  wrote on last edited by
                  #8

                  @ChrisWeiter said in Randomly Occuring assertion error:

                  @aha_1980 why do you doubt I need threads? I'm not eager to use them, but as I interface the sensors via a socket connection

                  E.g. because Qt provides an asynchronous API for sockets already. No need for threads.

                  Regards

                  Qt has to stay free or it will die.

                  1 Reply Last reply
                  1
                  • C ChrisWeiter

                    @CKurdu said in Randomly Occuring assertion error:

                    @ChrisWeiter

                    It seems also QObject::connect is in the wrong place. I am not sure also your Runnables is correct. QObject::connect should be placed after the "QThreadPool::globalInstance()->start(m_ControlThread,0);". All of your Runnable slots should connect a worker class that should be created in your Runnable::run method and Runnable::run method should end an exec() to start event queue.

                    Can you send your Runnable class. May be I can help correctly.

                    Thanks CKurdu. With your hints I was able to fix it.
                    Because I ran into some difficulties earlier, I moved all the code from the run to the constructor.
                    The solution was to initialize the worker in the constructor, but do the connections in the run().

                    Below the working code.

                    CCommRunnable::CCommRunnable(QString DeviceIp, DeviceType DeviceTypeIndicator)
                    {
                        WorkerDataCollector = new CDataCollector(DeviceIp);
                    }
                    
                    void CCommRunnable::run()
                    {
                        QObject::connect(this,&CBasisRunnable::sigDoWork,WorkerDataCollector,
                            &CDataCollector::onDoWork,Qt::QueuedConnection);
                       QObject::connect(WorkerDataCollector,&CDataCollector::sigNewData,this,
                        &CCommRunnable::sltonValuesChanged,Qt::QueuedConnection);
                    
                        m_EventLoop.exec(QEventLoop::AllEvents);
                    }
                    

                    @kshegunov considering your comment on the connection, I'm going to remove the parameter.
                    @aha_1980 why do you doubt I need threads? I'm not eager to use them, but as I interface the sensors via a socket connection it seemed best to me, to make the different parts of my code independent from the responsiveness of the connection. And probably there will be added more stuff to interface in the future.

                    CKurduC Offline
                    CKurduC Offline
                    CKurdu
                    wrote on last edited by
                    #9

                    @ChrisWeiter

                    I am sorry. It seems you have the wrong usage. You should create your worker in the run method.
                    You should read the link that @aha_1980 has been sent more carefully.

                    You reap what you sow it

                    1 Reply Last reply
                    0
                    • C ChrisWeiter

                      @CKurdu said in Randomly Occuring assertion error:

                      @ChrisWeiter

                      It seems also QObject::connect is in the wrong place. I am not sure also your Runnables is correct. QObject::connect should be placed after the "QThreadPool::globalInstance()->start(m_ControlThread,0);". All of your Runnable slots should connect a worker class that should be created in your Runnable::run method and Runnable::run method should end an exec() to start event queue.

                      Can you send your Runnable class. May be I can help correctly.

                      Thanks CKurdu. With your hints I was able to fix it.
                      Because I ran into some difficulties earlier, I moved all the code from the run to the constructor.
                      The solution was to initialize the worker in the constructor, but do the connections in the run().

                      Below the working code.

                      CCommRunnable::CCommRunnable(QString DeviceIp, DeviceType DeviceTypeIndicator)
                      {
                          WorkerDataCollector = new CDataCollector(DeviceIp);
                      }
                      
                      void CCommRunnable::run()
                      {
                          QObject::connect(this,&CBasisRunnable::sigDoWork,WorkerDataCollector,
                              &CDataCollector::onDoWork,Qt::QueuedConnection);
                         QObject::connect(WorkerDataCollector,&CDataCollector::sigNewData,this,
                          &CCommRunnable::sltonValuesChanged,Qt::QueuedConnection);
                      
                          m_EventLoop.exec(QEventLoop::AllEvents);
                      }
                      

                      @kshegunov considering your comment on the connection, I'm going to remove the parameter.
                      @aha_1980 why do you doubt I need threads? I'm not eager to use them, but as I interface the sensors via a socket connection it seemed best to me, to make the different parts of my code independent from the responsiveness of the connection. And probably there will be added more stuff to interface in the future.

                      CKurduC Offline
                      CKurduC Offline
                      CKurdu
                      wrote on last edited by
                      #10

                      @ChrisWeiter
                      hi,
                      Look at this link that I created for you. Build and run and look at thread's output. You will see all threads different. Then move line 17 into line 12 in RunnableOne.cpp then build and run. You will see all threads same.

                      Look at Thread Affinity for more information.

                      I don't know you really need threads. If you have long progress before sending a message to a socket, you can do it with threads.
                      Also, I am not sure that my example is proper for your needs because I created from your code structure. It needs more stabilizations.

                      I am warning you, threads really create unexpectable results. I hope I helped you.

                      You reap what you sow it

                      1 Reply Last reply
                      1

                      • Login

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