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. Get sigabrt exception when I try to send data using QTcpSocket to InfluxDB
Qt 6.11 is out! See what's new in the release blog

Get sigabrt exception when I try to send data using QTcpSocket to InfluxDB

Scheduled Pinned Locked Moved Unsolved General and Desktop
15 Posts 5 Posters 2.0k 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.
  • Christian EhrlicherC Christian Ehrlicher

    Provide some code or even better a testcase.
    For me it looks like you either access data from two different threads without proper locking or access the socket from two different threads.

    Why do you have such a strange time constraint on the main thread?

    A Offline
    A Offline
    AmitParmar
    wrote on last edited by
    #6

    @Christian-Ehrlicher
    As I said, Its a real-time application. We have time-critical tools running on production floor. It could damage the products in case the main thread gets blocked.

    Let me try to write some sample code and try to create similar scenario. Will post some code soon.

    Thanks,
    Amit

    1 Reply Last reply
    1
    • A Offline
      A Offline
      AmitParmar
      wrote on last edited by
      #7

      Hello Friends,

      Sorry for the delay.
      I have attached the code which creates similar scenario of my application. Instead of GUI, our application is a service which has infinitely running main thread. Since It is time-critical application, every function has to be completed in less than 20 milliseconds.

      #include "mainwindow.h"
      #include "ui_mainwindow.h"
      
      MainWindow::MainWindow(QWidget *parent)
          : QMainWindow(parent)
          , ui(new Ui::MainWindow)
      {
          ui->setupUi(this);
          socket = new QTcpSocket(this);
      
          timer = new QTimer(this);
          timer->setInterval(20);
      
          tcpThread = new QThread(this);
      
          connect(socket, SIGNAL(connected()),this, SLOT(connected()));
          connect(socket, SIGNAL(disconnected()),this, SLOT(disconnected()));
          connect(socket, SIGNAL(readyRead()),this, SLOT(readyRead()));
          QObject::connect(timer, SIGNAL(timeout()), this, SLOT(SendData()));
      
          socket->moveToThread(tcpThread);
          doConnect();
      
          tcpThread->start();
      
          header = QByteArray("POST /api/v2/write?org=ABC&bucket=AAA&precision=ns HTTP/1.1\r\nHost: localhost:8086\r\nAuthorization: Token UtUW9twti\r\nContent-Type: application/vnd.flux; charset=utf-8\r\nContent-Length: ");
      }
      
      MainWindow::~MainWindow()
      {
          tcpThread->quit();
          timer->stop();
      
          socket->disconnect();
          delete tcpThread;
          delete socket;
          delete timer;
      
          delete ui;
      }
      
      void MainWindow::connected()
      {
          qDebug() << "connected...";
      }
      
      void MainWindow::doConnect()
      {
          qDebug() << "connecting...";
      
          // this is not blocking call
          socket->connectToHost(QString::fromLocal8Bit("localhost"), 8086);
      
          if(!socket->waitForConnected(5000))
          {
          // we need to wait... << "Error: " << socket->errorString();
          }
      }
      
      void MainWindow::readyRead()
      {
          qDebug() << "reading...";
      
          // read the data from the socket
          auto rep = socket->readAll();
      
          qDebug() << rep;
          if(rep.contains("400") && rep.contains("Connection: close"))
          {
              qDebug() << "Connection: Closed >>";
          }
      }
      
      void MainWindow::disconnected()
      {
          qDebug() << "disconnected...";
      }
      
      void MainWindow::on_pushButton_clicked()
      {
          timer->start(20);
      }
      
      QByteArray MainWindow::CollectData()
      {
          //This function collect data from various parts of the tool at real-time.
          QByteArray("Data, Tool=A, temp=200,X=40,Y=20.5,Z=8.8");
      }
      
      void MainWindow::SendData()
      {
           QByteArray infline = CollectData();
          if(socket->isOpen())
          {
              auto res = socket->write(header + QByteArray::number(infline.length()) + "\r\n\r\n");
              res = socket->write(infline);
          }
      }
      
      

      I ran more test on my application and got more meaning-full error trace this time. Clearly it has something to do with Write & Read operations. I know, QAbstractSocket class is not thread safe. Is it a synchronisation issue? Is there anything else causing problem? Can somebody please help?

      Caught SIGABRT
      /opt/bin/test(+0x395ce) [0x55beea4995ce]
      /lib/x86_64-linux-gnu/libc.so.6(+0x43090) [0x7f0108c86090]
      /lib/x86_64-linux-gnu/libc.so.6(gsignal+0xcb) [0x7f0108c8600b]
      /lib/x86_64-linux-gnu/libc.so.6(abort+0x12b) [0x7f0108c65859]
      /lib/x86_64-linux-gnu/libc.so.6(+0x8d26e) [0x7f0108cd026e]
      /lib/x86_64-linux-gnu/libc.so.6(+0x952fc) [0x7f0108cd82fc]
      /lib/x86_64-linux-gnu/libc.so.6(+0x9596b) [0x7f0108cd896b]
      /lib/x86_64-linux-gnu/libc.so.6(+0x96e8b) [0x7f0108cd9e8b]
      /lib/x86_64-linux-gnu/libc.so.6(+0x98f22) [0x7f0108cdbf22]
      /lib/x86_64-linux-gnu/libc.so.6(realloc+0x2d6) [0x7f0108cde156]
      QByteArray::realloc(int)
      QByteArray::resize(int)
      QAbstractSocket::readData(char
      , long long)
      QIODevice::read(char
      , long long)
      QIODevice::readAll()
      **
      test::threads::MasterThread::_writeToMapFile()
      test::threads::MasterThread::writeDataToMapFile()
      test::threads::MasterThread::process()
      /opt/lib/libtest_core.so.1(+0x44e025) [0x7f010990e025]
      /opt/lib/libQtCore-test.so.4(+0xab622) [0x7f01092be622]
      /lib/x86_64-linux-gnu/libpthread.so.0(+0x8609) [0x7f010903c609]
      /lib/x86_64-linux-gnu/libc.so.6(clone+0x43) [0x7f0108d62133]

      Regards,
      Amit

      JonBJ 1 Reply Last reply
      0
      • A AmitParmar

        Hello Friends,

        Sorry for the delay.
        I have attached the code which creates similar scenario of my application. Instead of GUI, our application is a service which has infinitely running main thread. Since It is time-critical application, every function has to be completed in less than 20 milliseconds.

        #include "mainwindow.h"
        #include "ui_mainwindow.h"
        
        MainWindow::MainWindow(QWidget *parent)
            : QMainWindow(parent)
            , ui(new Ui::MainWindow)
        {
            ui->setupUi(this);
            socket = new QTcpSocket(this);
        
            timer = new QTimer(this);
            timer->setInterval(20);
        
            tcpThread = new QThread(this);
        
            connect(socket, SIGNAL(connected()),this, SLOT(connected()));
            connect(socket, SIGNAL(disconnected()),this, SLOT(disconnected()));
            connect(socket, SIGNAL(readyRead()),this, SLOT(readyRead()));
            QObject::connect(timer, SIGNAL(timeout()), this, SLOT(SendData()));
        
            socket->moveToThread(tcpThread);
            doConnect();
        
            tcpThread->start();
        
            header = QByteArray("POST /api/v2/write?org=ABC&bucket=AAA&precision=ns HTTP/1.1\r\nHost: localhost:8086\r\nAuthorization: Token UtUW9twti\r\nContent-Type: application/vnd.flux; charset=utf-8\r\nContent-Length: ");
        }
        
        MainWindow::~MainWindow()
        {
            tcpThread->quit();
            timer->stop();
        
            socket->disconnect();
            delete tcpThread;
            delete socket;
            delete timer;
        
            delete ui;
        }
        
        void MainWindow::connected()
        {
            qDebug() << "connected...";
        }
        
        void MainWindow::doConnect()
        {
            qDebug() << "connecting...";
        
            // this is not blocking call
            socket->connectToHost(QString::fromLocal8Bit("localhost"), 8086);
        
            if(!socket->waitForConnected(5000))
            {
            // we need to wait... << "Error: " << socket->errorString();
            }
        }
        
        void MainWindow::readyRead()
        {
            qDebug() << "reading...";
        
            // read the data from the socket
            auto rep = socket->readAll();
        
            qDebug() << rep;
            if(rep.contains("400") && rep.contains("Connection: close"))
            {
                qDebug() << "Connection: Closed >>";
            }
        }
        
        void MainWindow::disconnected()
        {
            qDebug() << "disconnected...";
        }
        
        void MainWindow::on_pushButton_clicked()
        {
            timer->start(20);
        }
        
        QByteArray MainWindow::CollectData()
        {
            //This function collect data from various parts of the tool at real-time.
            QByteArray("Data, Tool=A, temp=200,X=40,Y=20.5,Z=8.8");
        }
        
        void MainWindow::SendData()
        {
             QByteArray infline = CollectData();
            if(socket->isOpen())
            {
                auto res = socket->write(header + QByteArray::number(infline.length()) + "\r\n\r\n");
                res = socket->write(infline);
            }
        }
        
        

        I ran more test on my application and got more meaning-full error trace this time. Clearly it has something to do with Write & Read operations. I know, QAbstractSocket class is not thread safe. Is it a synchronisation issue? Is there anything else causing problem? Can somebody please help?

        Caught SIGABRT
        /opt/bin/test(+0x395ce) [0x55beea4995ce]
        /lib/x86_64-linux-gnu/libc.so.6(+0x43090) [0x7f0108c86090]
        /lib/x86_64-linux-gnu/libc.so.6(gsignal+0xcb) [0x7f0108c8600b]
        /lib/x86_64-linux-gnu/libc.so.6(abort+0x12b) [0x7f0108c65859]
        /lib/x86_64-linux-gnu/libc.so.6(+0x8d26e) [0x7f0108cd026e]
        /lib/x86_64-linux-gnu/libc.so.6(+0x952fc) [0x7f0108cd82fc]
        /lib/x86_64-linux-gnu/libc.so.6(+0x9596b) [0x7f0108cd896b]
        /lib/x86_64-linux-gnu/libc.so.6(+0x96e8b) [0x7f0108cd9e8b]
        /lib/x86_64-linux-gnu/libc.so.6(+0x98f22) [0x7f0108cdbf22]
        /lib/x86_64-linux-gnu/libc.so.6(realloc+0x2d6) [0x7f0108cde156]
        QByteArray::realloc(int)
        QByteArray::resize(int)
        QAbstractSocket::readData(char
        , long long)
        QIODevice::read(char
        , long long)
        QIODevice::readAll()
        **
        test::threads::MasterThread::_writeToMapFile()
        test::threads::MasterThread::writeDataToMapFile()
        test::threads::MasterThread::process()
        /opt/lib/libtest_core.so.1(+0x44e025) [0x7f010990e025]
        /opt/lib/libQtCore-test.so.4(+0xab622) [0x7f01092be622]
        /lib/x86_64-linux-gnu/libpthread.so.0(+0x8609) [0x7f010903c609]
        /lib/x86_64-linux-gnu/libc.so.6(clone+0x43) [0x7f0108d62133]

        Regards,
        Amit

        JonBJ Online
        JonBJ Online
        JonB
        wrote on last edited by
        #8

        @AmitParmar
        I don't know if this helps. What is your test::threads::MasterThread stuff? If that is calling socket->readAll() then, so far as I understand, that must only be called from the thread in which socket lives/has been moved to, i.e. tcpThread. Is that the case/not the case?

        1 Reply Last reply
        0
        • A Offline
          A Offline
          AmitParmar
          wrote on last edited by
          #9

          Sorry for the confusion. The stack trace, I posted was from my actual application where as the code, I posted was the test code I wrote for creating same scenario to my actual application.

          Here's the part of the code from my actual application. As you can see, MasterThread is main thread and m_influxDBThread is for sending/receiving data.

          Hopefully, It gives more idea.

          MasterThread::MasterThread(double interval) : 
          BaseThread(new MasterThreadObject(this)),
           m_influxDBSocket(new QTcpSocket),
           m_influxDBThread(new QThread)
          {
              m_influxDBThread->start();
          }
          
          void MasterThread::ReadyRead()
          {
              if(m_influxDBSocket->bytesAvailable() > 0)
              {
                  m_resp = m_influxDBSocket->readAll();
                  if(m_resp.contains("400") || m_resp.contains("413") || m_resp.contains("429") || m_resp.contains("500") || m_resp.contains("503"))
                  {
                      qDebug() << "error";
                  }
              }
          }
          
          void MasterThread::_writeToMapFile()
          {
              m_influxDBSocket->write(m_influxDBHeader + QByteArray::number(len) + "\r\n\r\n");
          
              foreach (const QByteArray &tag, m_influxDBLines.keys())
              {
                  QByteArray dataline = QByteArray(*m_influxDBLines.value(tag));
                  auto datalength = dataline.length();
          
                  if(datalength > 0)
                  {
                      long bytewritten = m_influxDBSocket->write(dataline);
                  }
              }
          }
          
          bool MasterThread::setInfluxDB()
          {
              m_influxDBSocket->connectToHost(QString::fromLocal8Bit(host), port);
              
              if (!m_influxDBSocket->waitForConnected())
              {
                  return false;
              }
          
              m_influxDBSocket->moveToThread(m_influxDBThread);
              connect(m_influxDBSocket, SIGNAL(readyRead()), this, SLOT(ReadyRead()), Qt::DirectConnection);
          }
          
          1 Reply Last reply
          0
          • K Offline
            K Offline
            kuzulis
            Qt Champions 2020
            wrote on last edited by kuzulis
            #10

            Wrong yet.

            You need to call the socket methods from that thread, where the socket lives.

            You need to create the socket without of a parent , before moving to a thread.

            To call the methods, you can use the invokeMethod function , or the signals/slots with the queued type.

            To check that a method is called from the right thread, print the current thread id inside of a caller.

            Or, do not use a threads without if a important reason.

            Christian EhrlicherC 1 Reply Last reply
            1
            • K kuzulis

              Wrong yet.

              You need to call the socket methods from that thread, where the socket lives.

              You need to create the socket without of a parent , before moving to a thread.

              To call the methods, you can use the invokeMethod function , or the signals/slots with the queued type.

              To check that a method is called from the right thread, print the current thread id inside of a caller.

              Or, do not use a threads without if a important reason.

              Christian EhrlicherC Offline
              Christian EhrlicherC Offline
              Christian Ehrlicher
              Lifetime Qt Champion
              wrote on last edited by
              #11

              @kuzulis said in Get sigabrt exception when I try to send data using QTcpSocket to InfluxDB:

              You need to call the socket methods from that thread, where the socket lives.

              For me it looks like you either access data from two different threads without proper locking or access the socket from two different threads.

              Some people are simply not reading or ignoring the hints they were given... and then wonder when they get no answers anymore.

              Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
              Visit the Qt Academy at https://academy.qt.io/catalog

              A 1 Reply Last reply
              0
              • Christian EhrlicherC Christian Ehrlicher

                @kuzulis said in Get sigabrt exception when I try to send data using QTcpSocket to InfluxDB:

                You need to call the socket methods from that thread, where the socket lives.

                For me it looks like you either access data from two different threads without proper locking or access the socket from two different threads.

                Some people are simply not reading or ignoring the hints they were given... and then wonder when they get no answers anymore.

                A Offline
                A Offline
                AmitParmar
                wrote on last edited by
                #12

                @Christian-Ehrlicher

                Hey Chris,
                I already got your point and understand your hints. I also found out QAbstractClass is not thread safe which seems culprit in this case but believe me, I already tried to run application by locking Read & Write operations with mutex so many times. It didnt work somehow.

                If you know any code or any test application which has similar scenarios, Could you please point me out? Sorry, I am not very good with QT framework.

                Right now, I am trying to understand and implement, kuzulis's points into my application.

                Christian EhrlicherC 1 Reply Last reply
                0
                • A AmitParmar

                  @Christian-Ehrlicher

                  Hey Chris,
                  I already got your point and understand your hints. I also found out QAbstractClass is not thread safe which seems culprit in this case but believe me, I already tried to run application by locking Read & Write operations with mutex so many times. It didnt work somehow.

                  If you know any code or any test application which has similar scenarios, Could you please point me out? Sorry, I am not very good with QT framework.

                  Right now, I am trying to understand and implement, kuzulis's points into my application.

                  Christian EhrlicherC Offline
                  Christian EhrlicherC Offline
                  Christian Ehrlicher
                  Lifetime Qt Champion
                  wrote on last edited by
                  #13

                  @AmitParmar said in Get sigabrt exception when I try to send data using QTcpSocket to InfluxDB:

                  Right now, I am trying to understand and implement, kuzulis's points into my application.

                  So you could hav done this already 9 days ago since I already guessed that you're accessing the socket from two different threads, exactly what @kuzulis told you now again.

                  Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                  Visit the Qt Academy at https://academy.qt.io/catalog

                  1 Reply Last reply
                  0
                  • A Offline
                    A Offline
                    AmitParmar
                    wrote on last edited by
                    #14

                    Ohh, I am sorry, I think I miss-understood your comment. I thought you are suggesting me to lock read/write operations so, multiple threads cannot access them at the same time. Anyway, thanks again for the help. Appreciate it.

                    Also, do you know if there is any similar application or test code which I can look as a reference?

                    Christian EhrlicherC 1 Reply Last reply
                    0
                    • A AmitParmar

                      Ohh, I am sorry, I think I miss-understood your comment. I thought you are suggesting me to lock read/write operations so, multiple threads cannot access them at the same time. Anyway, thanks again for the help. Appreciate it.

                      Also, do you know if there is any similar application or test code which I can look as a reference?

                      Christian EhrlicherC Offline
                      Christian EhrlicherC Offline
                      Christian Ehrlicher
                      Lifetime Qt Champion
                      wrote on last edited by
                      #15

                      @AmitParmar said in Get sigabrt exception when I try to send data using QTcpSocket to InfluxDB:

                      nt. I thought you are suggesting me to lock read/write operations so,

                      I also said that you may access the socket from different threads what you're obviously doing - you access a socket from another thread where it lives in.

                      Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                      Visit the Qt Academy at https://academy.qt.io/catalog

                      1 Reply Last reply
                      0

                      • Login

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