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. [SOLVED] QSerialPort and Invalid address specified to RtlFreeHeap
Forum Updated to NodeBB v4.3 + New Features

[SOLVED] QSerialPort and Invalid address specified to RtlFreeHeap

Scheduled Pinned Locked Moved General and Desktop
16 Posts 2 Posters 6.9k 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.
  • K Offline
    K Offline
    kuzulis
    Qt Champions 2020
    wrote on last edited by
    #7

    [quote]
    Furthermore, Invalid address specified to RtlFreeHeap isn’t the only problem I have got with QSerialPort. In early Qt 5 versions when it had support for this class almost out of the box it had some problems with QStreams.
    [/quote]

    These are all unfounded statements which have no value. And it isn't important that you there wrote your wrappers at yourselves earlier.

    You at all didn't provide any code. Therefore, most likely a problem in your code.

    [quote]
    Are there any other good alternatives which have multi platform support and are relatively light?
    [/quote]

    Use boost::asio or your custom wrapper, what problem?

    1 Reply Last reply
    0
    • Y Offline
      Y Offline
      y0yster
      wrote on last edited by
      #8

      This is exactly why I have written what I had used before. Therefore, I'm pretty convenient that the error isn't because of my code. Also I've given a reason why I don't use other solutions any more.

      Here is the function trace when I get the message with error:
      0 ntdll!RtlpNtSetValueKey C:\Windows\SYSTEM32\ntdll.dll 0x770713f7
      1 ntdll!RtlpNtSetValueKey C:\Windows\SYSTEM32\ntdll.dll 0x77070311
      2 ntdll!LdrSetAppCompatDllRedirectionCallback C:\Windows\SYSTEM32\ntdll.dll 0x77024e37
      3 ?? 0x1662d998
      4 ntdll!RtlFreeHeap C:\Windows\SYSTEM32\ntdll.dll 0x76fcfac9
      5 msvcrt!free C:\Windows\SysWOW64\msvcrt.dll 0x767b9a15
      6 ?? 0x141d0000
      7 QArrayData::deallocate 130 0x6b799e14
      8 QTypedArrayData<char>::deallocate 234 0x6b9cb89d
      9 QByteArray::resize 1448 0x6b79bc2b
      10 QRingBuffer::append 383 0x6458963e
      11 QSerialPortPrivate::_q_completeAsyncRead 608 0x645855af
      12 QSerialPort::qt_static_metacall 348 0x64582d8e
      13 QMetaObject::activate 3680 0x6b954ee9
      14 QMetaObject::activate 3546 0x6b95484e
      15 QWinEventNotifier::activated 134 0x6b9ad11d
      16 QWinEventNotifier::event 241 0x6b976955
      17 QApplicationPrivate::notify_helper 3522 0x8c1e09f
      18 QApplication::notify 2975 0x8c1bb51
      19 QCoreApplication::notifyInternal 935 0x6b929dde
      20 QCoreApplication::sendEvent 237 0x6b9cf187
      21 QEventDispatcherWin32Private::activateEventNotifier 335 0x6b978188
      22 QEventDispatcherWin32::processEvents 759 0x6b979887
      23 QWindowsGuiEventDispatcher::processEvents 80 0x6285cdc0
      24 QEventLoop::processEvents 136 0x6b927e84
      25 QEventLoop::exec 212 0x6b92811f
      26 QCoreApplication::exec 1188 0x6b92a42d
      27 QGuiApplication::exec 1450 0xb062e2
      28 QApplication::exec 2767 0x8c1b495
      29 qMain main.cpp 10 0x401653
      30 WinMain@16 131 0x408a7d
      31 main 0x41cccd

      If you could please look at entry 8 to 12 you will see that something is going on with QSerialPort. I get this message randomly but mos often at the very beginning of the transmission.

      1 Reply Last reply
      0
      • K Offline
        K Offline
        kuzulis
        Qt Champions 2020
        wrote on last edited by
        #9

        It doesn't speak about anything that problem is in QtSerialPort. Once again I will repeat: most likely you do something wrong (I am sure). But without a source code I can help nothing.

        UPD: The most important mistake - the QtSerialPort can't use from different threads (even if to use mutexes, etc.). Because internally the QtSerialPort works not as you think.

        1 Reply Last reply
        0
        • Y Offline
          Y Offline
          y0yster
          wrote on last edited by
          #10

          How it doesn't say nothing about QSerialPort? There are:
          11 QSerialPortPrivate::_q_completeAsyncRead 608 0×645855af
          12 QSerialPort::qt_static_metacall 348 0×64582d8e
          which indicates that it operates on the memory and then the crash occurs.

          When I've used for example boost for reading from serial port nothing like that happened.

          Update:
          Here is the source code responsible for reading data from QSerialPort:

          @
          int ComPort::read( char * Buffer, int Count)
          {
          int i;

          mutex.lock();
          
          if( !_Port.isOpen())
          {
            mutex.unlock();
            return -2;
          }
          
          int available_bytes;
          
          available_bytes = _Port.bytesAvailable();
          
          if( Count <= available_bytes)
            available_bytes = Count;
          
          qDebug() << "<- in";
          i = _Port.read( Buffer, available_bytes);
          qDebug() << "-> out";
          
          mutex.unlock();
          
          return i;
          

          }
          @

          During debugging I can only get "<- in" string but no "-> out".

          Update:
          So, is there a workaround to do this? I mean using QSerialPort from another thread.

          1 Reply Last reply
          0
          • K Offline
            K Offline
            kuzulis
            Qt Champions 2020
            wrote on last edited by
            #11

            bq. Here is the source code responsible for reading data from QSerialPort:

            This is wrong. Because port.read() reads data from the internal buffer of class (QRingBuffer). Thus, this internal buffer isn't protected on write to it. This writing to the read buffer (buffer.append()) is carried out inside of the class when RX_EVENT triggered. So, it lead to data corruption in your case.

            So, you all do wrong..

            bq. So, is there a workaround to do this? I mean using QSerialPort from another thread.

            You should move whole QtSerialPort instance to another thread (i.e. access to the all serial port's methods has to be provided always from one thread). And then use signals/slots for data transferring. In this case the mutexes do not need at all.

            1 Reply Last reply
            0
            • Y Offline
              Y Offline
              y0yster
              wrote on last edited by
              #12

              I did what you suggested with several variations.
              Like before I have wrapper class for QSerialPort:

              @ ComPort::ComPort(QObject *parent) :
              _BytesWaiting(0),
              _BaudRate( QSerialPort::Baud115200),
              _Parity( QSerialPort::NoParity),
              _StopBits( QSerialPort::OneStop),
              _FlowControl( QSerialPort::NoFlowControl),
              _DataBits( QSerialPort::Data8),
              QObject(parent),
              Stream(Buffer)
              {
              ThreadCom = new QThread;
              _Port = new QSerialPort();

              connect(_Port, SIGNAL(readyRead()), this, SLOT(handleReadyRead()));
              
              _Port->moveToThread( ThreadCom);
              ThreadCom->start();
              

              }@

              Also in the GUI I have:

              @ ThreadForCom = new QThread;
              SerialPort = new ComPort::ComPort();
              SerialPort->moveToThread(ThreadForCom);

              ThreadForCom->start();@

              However, this doesn't work. I don't get any data. But when in my wrapper class I let go of QThread:

              @ ComPort::ComPort(QObject *parent) :
              _BytesWaiting(0),
              _BaudRate( QSerialPort::Baud115200),
              _Parity( QSerialPort::NoParity),
              _StopBits( QSerialPort::OneStop),
              _FlowControl( QSerialPort::NoFlowControl),
              _DataBits( QSerialPort::Data8),
              QObject(parent),
              Stream(Buffer)
              {
              _Port = new QSerialPort();

              connect(_Port, SIGNAL(readyRead()), this, SLOT(handleReadyRead()));
              

              }@

              It works but not completely. It seams that I'm loosing data and also the messages which I get are corrupted.

              Edit:
              Here is how I handle the oncoming data:
              @ void ComPort::handleReadyRead(void)
              {
              mutex.lock();
              Buffer.append(_Port->readAll());
              mutex.unlock();
              }@

              Here is reading procedure:
              @int ComPort::read( char * Buffer, int Count)
              {
              mutex.lock();

              if( !_Port->isOpen())
              {
                mutex.unlock();
                return -2;
              }
              
              int available_bytes;
              
              available_bytes = this->Buffer.count();
              
              if( Count <= available_bytes)
                available_bytes = Count;
              
              memcpy( Buffer, this->Buffer.data(), available_bytes);
              this->Buffer.remove(0, available_bytes);
              
              mutex.unlock();
              
              return available_bytes;
              

              }@

              1 Reply Last reply
              0
              • K Offline
                K Offline
                kuzulis
                Qt Champions 2020
                wrote on last edited by
                #13

                @
                class Worker : public QSerialPort
                {
                public:
                Worker(QObject *parent = 0)
                : QSerialPort(parent)
                {

                    open(...);
                    setBaudRate(...);
                    ...
                    setParity(...);
                
                    conenct(this, SIGNAL(readyRead()), this, SLOT(handleReadyRead()));
                }
                

                signals:
                void dataReceived(constQByteArray &data);

                private slots:
                void handleReadyRead()
                {
                const QByteArray data = readAll();
                emit dataReceived(data);
                }
                }

                ...
                worker = new Worker();
                thread = new QThread();
                worker->moveToThread(thread);
                thread->start();
                ...
                @

                1 Reply Last reply
                0
                • Y Offline
                  Y Offline
                  y0yster
                  wrote on last edited by
                  #14

                  I did apply your suggestions. Now, I don't have a single mutex in my application. After some changes everything is working in signal/slot spirit. However, it seems like data are being lost, actually like lots of it is corrupted. This also happened before the change. What can be responsible for this?

                  1 Reply Last reply
                  0
                  • K Offline
                    K Offline
                    kuzulis
                    Qt Champions 2020
                    wrote on last edited by
                    #15

                    bq. However, it seems like data are being lost, actually like lots of it is corrupted.

                    It can't be in principle (impossible).

                    bq. What can be responsible for this?

                    Try to check for correct configuration of your serialport.

                    1 Reply Last reply
                    0
                    • Y Offline
                      Y Offline
                      y0yster
                      wrote on last edited by
                      #16

                      Problem was solved. Now everything works just fine.
                      The reason for the message being corrupted was the way of handling the data. It required me to remove the data from temporary buffer. Unless the algorithm would look for start sequence inside the data which has been already processed.

                      To sum up the main problem of the Invalid address specified to RtlFreeHeap. QSerialPort can't be used between threads even the memory is protected by mutexes.

                      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