Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LwIP memory leak - I posted this to closed issue 1829 so I'm posting it again here (IDFGH-6517) #8168

Closed
BojanJurca opened this issue Dec 29, 2021 · 4 comments
Labels
Resolution: Done Issue is done internally Status: Done Issue is done internally

Comments

@BojanJurca
Copy link

Environment

Arduino 1.8.16, ESP32 Dev Module

  • Operating System: Windows
  • (Windows only) environment type:
  • Using an IDE?: Arduino 1.8.16
  • Power Supply: USB

Problem Description

LwIP is loosing memory for each TCP connection that arrives to TCP server.

Expected Behavior

Whole heap memory to be regained after 2 minutes.

Actual Behavior

104 bytes of heap gets lost.

Steps to reproduce

Run the code.

Code to reproduce this issue

#include <WiFi.h>
#include <lwip/sockets.h>

void setup () {
  Serial.begin (115200);
  WiFi.begin ("ZTE_C8151C", "*****");
  WiFi.mode (WIFI_STA); 
  while (WiFi.localIP ().toString () == "0.0.0.0") { delay (1000); Serial.printf ("   .\n"); } // wait until we get IP from router
  Serial.printf ("Got IP: %s\n", (char *) WiFi.localIP ().toString ().c_str ());

  // display free memmory twice a minute: freeHeap to check memory leaks, max memory block to check memory fragmentation
  xTaskCreate ([] (void * pvParameters) { 
                                          while (true) {
                                            Serial.printf ("--- Free heap: %6lu --- max memory block: %6lu ---\n", (unsigned long) ESP.getFreeHeap (), (unsigned long) heap_caps_get_largest_free_block (MALLOC_CAP_DEFAULT));
                                            delay (30000);
                                          }
                                        }, "memoryTest", 2048, NULL, 1, NULL);
                                        
  // a very basic TCP (web) server
  int listeningSocket = -1;
  listeningSocket = socket (PF_INET, SOCK_STREAM, 0);
  if (listeningSocket == -1) {
    Serial.printf ("(listener) socket error: %i\n", errno);
  } else {
    // make address reusable - so we won't have to wait a few minutes in case server will be restarted
    int flag = 1;
    if (setsockopt (listeningSocket, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof (flag)) == -1) {
      Serial.printf ("(listener) setsockopt error: %i\n", errno);
    } else {
     // bind listening socket to IP address and port     
     struct sockaddr_in serverAddress; 
     memset (&serverAddress, 0, sizeof (struct sockaddr_in));
     serverAddress.sin_family = AF_INET;
     serverAddress.sin_addr.s_addr = inet_addr ("0.0.0.0");
     serverAddress.sin_port = htons (80);
     if (bind (listeningSocket, (struct sockaddr *) &serverAddress, sizeof (serverAddress)) == -1) {
      Serial.printf ("(listener) bind error: %i\n", errno);
     } else {
       // mark socket as listening socket
       #define BACKLOG 8
       if (listen (listeningSocket, BACKLOG) == -1) {
        Serial.printf ("(listener) listen error: %i\n", errno);
       } else {

        // listener is ready for accepting connections
        Serial.printf ("A very basic TCP (web) server is waiting for new connections ...\n");
        while (true) {

            int connectingSocket;
            struct sockaddr_in connectingAddress;
            socklen_t connectingAddressSize = sizeof (connectingAddress);
            connectingSocket = accept (listeningSocket, (struct sockaddr *) &connectingAddress, &connectingAddressSize);
            if (connectingSocket == -1) {
              Serial.printf ("accept error: %i\n", errno);
            } else {
              Serial.printf ("New connection arrived, sending 404 reply ...\n");
              // don't even read the request, just reply with error 404 and break the connection
              char httpReply [] = "HTTP/1.1 404 Not found\r\nContent-Length:20\r\n\r\nPage does not exist.";
              if (send (connectingSocket, httpReply, strlen (httpReply), 0) == -1) {
                Serial.printf ("send error: %i\n", errno);
              }
              close (connectingSocket);
            }
            
        } // while accepting connections - for ever

       } // listen
     } // bind
    } // setsockopt
    close (listeningSocket); // never executes
  } // socket
   
}

void loop () {
  
}

Debug Logs

.
.
.
Got IP: 192.168.0.168
--- Free heap: 280712 --- max memory block: 113792 ---
A very basic TCP (web) server is waiting for new connections ...
--- Free heap: 279876 --- max memory block: 113792 ---
--- Free heap: 279876 --- max memory block: 113792 ---
--- Free heap: 279876 --- max memory block: 113792 ---
--- Free heap: 279736 --- max memory block: 113792 ---
--- Free heap: 279736 --- max memory block: 113792 ---
--- Free heap: 279736 --- max memory block: 113792 ---
--- Free heap: 279736 --- max memory block: 113792 ---
--- Free heap: 279736 --- max memory block: 113792 ---
New connection arrived, sending 404 reply ...
--- Free heap: 279248 --- max memory block: 113792 ---
--- Free heap: 279248 --- max memory block: 113792 ---
--- Free heap: 279248 --- max memory block: 113792 ---
--- Free heap: 279248 --- max memory block: 113792 ---
--- Free heap: 279492 --- max memory block: 113792 --- <- lost 244 bytes
--- Free heap: 279492 --- max memory block: 113792 ---
--- Free heap: 279492 --- max memory block: 113792 ---
--- Free heap: 279492 --- max memory block: 113792 ---
--- Free heap: 279492 --- max memory block: 113792 ---
New connection arrived, sending 404 reply ...
--- Free heap: 279144 --- max memory block: 113792 ---
--- Free heap: 279144 --- max memory block: 113792 ---
--- Free heap: 279144 --- max memory block: 113792 ---
--- Free heap: 279144 --- max memory block: 113792 ---
--- Free heap: 279388 --- max memory block: 113792 --- <- lost 104 bytes
--- Free heap: 279388 --- max memory block: 113792 ---
--- Free heap: 279388 --- max memory block: 113792 ---
--- Free heap: 277680 --- max memory block: 113792 ---
--- Free heap: 279388 --- max memory block: 113792 ---
--- Free heap: 279388 --- max memory block: 113792 ---
--- Free heap: 279388 --- max memory block: 113792 ---
--- Free heap: 279388 --- max memory block: 113792 ---
New connection arrived, sending 404 reply ...
--- Free heap: 279044 --- max memory block: 113792 ---
--- Free heap: 279044 --- max memory block: 113792 ---
--- Free heap: 279044 --- max memory block: 113792 ---
--- Free heap: 279044 --- max memory block: 113792 ---
--- Free heap: 279284 --- max memory block: 113792 --- <- lost 104 bytes
--- Free heap: 279284 --- max memory block: 113792 ---
@espressif-bot espressif-bot added the Status: Opened Issue is new label Dec 29, 2021
@github-actions github-actions bot changed the title LwIP memory leak - I posted this to closed issue 1829 so I'm posting it again here LwIP memory leak - I posted this to closed issue 1829 so I'm posting it again here (IDFGH-6517) Dec 29, 2021
@ESP-YJM
Copy link
Collaborator

ESP-YJM commented Dec 30, 2021

@BojanJurca Which IDF version you used.

@BojanJurca
Copy link
Author

ESP_IDF_VERSION_MAJOR 3
ESP_IDF_VERSION_MINOR 3
ESP_IDF_VERSION_PATCH 5

@ESP-YJM
Copy link
Collaborator

ESP-YJM commented Dec 30, 2021

@BojanJurca I think you can check this #7916 (comment).

@BojanJurca
Copy link
Author

This is it! Thank you. Once all 10 sockets are being used there is no memory leak any more for new connections. It is perfectly fine for me. I'm closing this issue.

@espressif-bot espressif-bot added Resolution: Done Issue is done internally Status: Done Issue is done internally and removed Status: Opened Issue is new labels Dec 30, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Resolution: Done Issue is done internally Status: Done Issue is done internally
Projects
None yet
Development

No branches or pull requests

3 participants