FreeRTPS+TCP memory leak

qwlimited wrote on Thursday, August 10, 2017:

Hello ,

I am new to FreeRTOS and +TCP, I create a simple echo server, almost every time when I connect/disconnect from echo server, there are 616 bytes gone.

echo heap: 26328
echo heap: 25712
echo heap: 25712
echo heap: 25712
echo heap: 25712
echo heap: 25096
echo heap: 25096
echo heap: 25096
echo heap: 25096
echo heap: 24480

My code as following, many thanks for your kind help

Kevin

/-----------------------------------------------------------------------------------/
void vTcpEchoTask(void *arg)
{
struct freertos_sockaddr xClient, xBindAddress;
Socket_t xListeningSocket, xConnectedSocket;
socklen_t xSize = sizeof( xClient );
static const TickType_t xReceiveTimeOut = portMAX_DELAY;
const BaseType_t xBacklog = 1;
static char cRxedData[ 128 ];
BaseType_t lBytesReceived;

/* Attempt to open the socket. */
xListeningSocket = FreeRTOS_socket( FREERTOS_AF_INET,
                                    FREERTOS_SOCK_STREAM,  /* SOCK_STREAM for TCP. */
                                    FREERTOS_IPPROTO_TCP );

/* Check the socket was created. */
configASSERT( xListeningSocket != FREERTOS_INVALID_SOCKET );

/* If FREERTOS_SO_RCVBUF or FREERTOS_SO_SNDBUF are to be used with
FreeRTOS_setsockopt() to change the buffer sizes from their default then do
it here!.  (see the FreeRTOS_setsockopt() documentation. */

/* If ipconfigUSE_TCP_WIN is set to 1 and FREERTOS_SO_WIN_PROPERTIES is to
be used with FreeRTOS_setsockopt() to change the sliding window size from
its default then do it here! (see the FreeRTOS_setsockopt()
documentation. */

/* Set a time out so accept() will just wait for a connection. */
FreeRTOS_setsockopt( xListeningSocket,
                     0,
                     FREERTOS_SO_RCVTIMEO,
                     &xReceiveTimeOut,
                     sizeof( xReceiveTimeOut ) );

/* Set the listening port to 7. */
xBindAddress.sin_port = ( uint16_t ) 7;
xBindAddress.sin_port = FreeRTOS_htons( xBindAddress.sin_port );

/* Bind the socket to the port that the client RTOS task will send to. */
FreeRTOS_bind( xListeningSocket, &xBindAddress, sizeof( xBindAddress ) );

/* Set the socket into a listening state so it can accept connections.
The maximum number of simultaneous connections is limited to 20. */
FreeRTOS_listen( xListeningSocket, xBacklog );

for( ;; )
{
    /* Wait for incoming connections. */
    xConnectedSocket = FreeRTOS_accept( xListeningSocket, &xClient, &xSize );
    configASSERT( xConnectedSocket != FREERTOS_INVALID_SOCKET );

printf(“echo heap: %d \n”, xPortGetFreeHeapSize() );
for(; :wink:
{
/* Receive another block of data into the cRxedData buffer. */
lBytesReceived = FreeRTOS_recv( xConnectedSocket, &cRxedData, 128, 0 );

        if( lBytesReceived > 0 )
        {
            /* Data was received, process it here. */
            //prvPorcessData( cRxedData, lBytesReceived );
            
            FreeRTOS_send( /* The socket being sent to. */
                                        xConnectedSocket,
                                        /* The data being sent. */
                                        &( cRxedData[ 0 ] ),
                                        /* The remaining length of data to send. */
                                        lBytesReceived,
                                        /*ulFlags. */
                                        0 );
        }
        else if( lBytesReceived == 0 )
        {
            /* No data was received, but FreeRTOS_recv() did not return an error.
            Timeout? */
        }
        else
        {
            /* Error (maybe the connected socket already shut down the socket?).
            Attempt graceful shutdown. */
            FreeRTOS_shutdown( xConnectedSocket, FREERTOS_SHUT_RDWR );
            break;
        }
    } //tcp_receive loop
    

    /* The RTOS task will get here if an error is received on a read.  Ensure the
    socket has shut down (indicated by FreeRTOS_recv() returning a FREERTOS_EINVAL
    error before closing the socket). */

    while( FreeRTOS_recv( xConnectedSocket, cRxedData, lBytesReceived, 0 ) >= 0 )
    {
        /* Wait for shutdown to complete.  If a receive block time is used then
        this delay will not be necessary as FreeRTOS_recv() will place the RTOS task
        into the Blocked state anyway. */
        osDelay(250  );

        /* Note - real applications should implement a timeout here, not just
        loop forever. */
    }

    /* Shutdown is complete and the socket can be safely closed. */
    FreeRTOS_closesocket( xConnectedSocket );
}

/* Must not drop off the end of the RTOS task - delete the RTOS task. */

osThreadTerminate(NULL);
}

rtel wrote on Friday, August 11, 2017:

Have you tried using the echo server that is provided in the labs download?

heinbali01 wrote on Friday, August 11, 2017:

Hi Kevin, I’m wondering what object uses 616 bytes.

We are not aware of any memory leak in the library.

The above code is a very simple demo, and it has one potential problem: while it is handling a client, a new client may connect to xListeningSocket. Connecting means that memory will be allocated to create a new socket. This might add up to 616 bytes ( socket space, a new event group ).

Correction: the xBacklog parameter has been set to 1, meaning that only a single client may connect at a time.

In this case, it would be helpful if you can trace all calls to pvPortMalloc() and vPortFree(), see who is claiming 616 bytes. Note that this may also exist of a few allocations ( X + Y + Z )

Please report back when you found the cause of the memory leak

qwlimited wrote on Friday, August 11, 2017:

Yes, I copied that code as shown above

qwlimited wrote on Friday, August 11, 2017:

Thanks Hein,
I will check and get back to you

qwlimited wrote on Monday, August 14, 2017:

Good morning Hein,

I checked it’s my problem in one of our calculation module, very sorry !

Best regards,
Kevin

heinbali01 wrote on Tuesday, August 15, 2017:

No problem, thank you very much for taking the effort to report back.