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
QtWS25 Last Chance

[SOLVED] QSerialPort and Invalid address specified to RtlFreeHeap

Scheduled Pinned Locked Moved General and Desktop
16 Posts 2 Posters 6.8k 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.
  • Y Offline
    Y Offline
    y0yster
    wrote on last edited by
    #1

    I have encountered a problem which is connected with QSerialPort. I am receiving a message from debugger as follows:
    Invalid address specified to RtlFreeHeap
    Inside function call list window I was able to identify it as a problem with QSerialPort. Furthermore, I have narrowed the problem to the read() method from QSerialPort class. Is there something that can be done about it?

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

      Please give simple example project that reproduce a problem. Also, what version of QtSerialPort do you use?

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

        It is hard to give a simple example because the problem I am encountering is a part of a bigger project. However, I will create a test project and check if the same problem occurs there.
        I'm using QSerialPort which comes with Qt 5.3.1.

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

          Unfortunately for me I can not reproduce this error with simple example. This does not occur with just reading the data from QSerialPort.
          I think that it can be something connected to threads and simultaneous access to the memory. However, I have also excluded that because I have a wrapper class for QSerialPort and mutex which guards the access to the device. So, I think this is not the case.

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

            It means that most likely your problem in the your application with lot of threads and mutexes. I at all don't understand, why you to use threads (with mutexes). For me it is strange approach...

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

              I am using threads and mutexes because I share memory between them.
              Yes, it may seem that the problem is with all the threads. However, using QSerialPort wasn't my first shoot. Before that I have written a library which works both for Windows and Linux system. It was fine until I decided to abandon this because I wanted to focus on the application development not on the interfaces. Also I have tested serial port support from ASIO boost. It was very good solution and it worked. Once again I also decided to abandon this because of long time which is required for compilation, and as far as I know it doesn't have forward declarations to speed up the process.
              As you can see this is not the problem with multiple threads and mutexes. It has something to do with the QSerialPort.
              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. Now, it has problems with memory deallocation (in debug mode) and with QList (element out of the reach in release mode).
              Are there any other good alternatives which have multi platform support and are relatively light?

              1 Reply Last reply
              0
              • 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