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

[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
    #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