Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

QIODevice readAll() function



  • hi all,

    I am reading data from socket as shown below and the error I am getting is: realloc(): invalid next size:... blah blah ..., obviously it is a memory issue.

    void TcpConnection::readyRead()
    {
        if(!sender()) return;
        qDebug() << this << "readyread" << m_socket->bytesAvailable();
        QByteArray dat = m_socket->readAll();
    }
    

    Few things I noticed:

    1. The error happens after it reads many times successfully.
    2. If I comment the code line with the readAll() fucntion, the bytesAvailables keeps adding normally and the app does not crash.
    3. If I the other end sends data slowly (every 100ms) I do not see this memory issue.

    The QT environment is running in a virtual machine with vitrtualbox and bridge network connections with the host.

    Thanks for helping.


  • Lifetime Qt Champion

    Your image shows exactly what we're telling you - you create and use the QTcpSocket from two different thread what is not allowed.



  • @Jc_Opc
    This code should not cause a problem. It is just possible that the " realloc(): invalid next size" comes from a problem elsewhere, which gets noticed here because readAll() will obviously do some memory allocation somewhere.

    Can you reproduce the problem in a program which does literally nothing but what you show?

    You will be probably be asked which version of Qt you are using, OS etc.



  • @JonB, based on your comment I tried a simple socket application and I noticed that it does not have any issues running in the same environment, the other big difference, I forgot to mention in my post, is that this socket is not running in the main thread. From the single thread test I just ran, I noticed that there were always bytes available, in the multithreading code I could see some of them are 0 bytes (the function bytesAvailable() is giving 0 bytes sometimes) . Any clue you may have is more than welcome, for now I will review my code and see if the functions I used are thread safe.

    thanks


  • Lifetime Qt Champion

    Where do you create the tcp socket? Hopefully in the same thread you're reading from it.



  • This is the way I create threads, TcpConnection wrapper and Socket

    1. Created pool of threads and threads based on number of SDR TcpConnections.
    2. Get the first available thread.
    3. Created a TcpConnection object which is a socket wrapper.
    4. Move the TcpConnection to that thread.
    5. Emit Signal that TcpConnection was created and passing the current thread pointer in order to create new socket.
    6. In the current Thread create the socket and wire signals.
      6.1. Wire signals between TcpConnection and socket.

    I am testing only one thread for now, besides the main GUI thread, and making sure that I am reading from the sender socket and current thread matches the same address when it was created.

    Thank you for your insight.


  • Lifetime Qt Champion

    QTcpSocket must be created in the same thread where you read/write from it. From my pov you don't do this but can't say exactly from your description.


  • Lifetime Qt Champion

    Hi,

    Based on your point number 4, it looks like you are doing the wrong thing. Do not move a socket between threads. Create it in the thread (not its constructor).



  • This is what I get when I run memcheck, please have a look at the image, unfortunately I could not export the results.

    I am following the last 2 comments and still working on them, when I was reading how to use sockets in threads, I knew sockets can not be passed between threads, but I will have a look again more carefully.

    Sorry for the image I do not know how to export the report from QT. Next time will use it from command line which I do not know yet but will find out.

    Thanks a lot.

    Screenshot from 2020-11-04 16-08-39.png


  • Lifetime Qt Champion

    Your image shows exactly what we're telling you - you create and use the QTcpSocket from two different thread what is not allowed.



  • Thanks a lot for your insight, double checking my runnable object Tcpthread which inherits QObject too; apart from the run() function, it has other functions and one of them was createSocket(), because this function was in the same runnable I thought it was part of the pooled thread but checking again with Qthread::currentThread, it was not, and I was passing this socket to the pooled thread which was causing the memory leak issue.

    Thanks a lot.



  • @Christian-Ehrlicher I tried to understand the log but I can't figure it out how you arrived to your conclusion. I can see that readAll() is in clone but I do not see it anywhere else. Can you please share how you noticed I was using the socket in 2 threads?

    Thanks.


  • Lifetime Qt Champion

    As you can see QRingBuffer is created in another thread. Since this is used from your QTcpSocket (first backtrace) the only way is that it was created in the main thread.


Log in to reply