Description
Board
ESP32-S3
Device Description
I can reproduce this with multiple ESP32 devboards, including an ESP32-S3 devkit-1. It also reproduces under Wokwi, see https://wokwi.com/projects/415900372828990465.
Version
3.0.7, 3.1.0-RC1
Description
When connecting and disconnecting from WiFi repeatedly, a small amount of memory is leaking during each iteration.
Sketch
#include <Arduino.h>
#include <WiFi.h>
void setup() {
Serial.begin(115200);
}
void loop() {
while (true) {
Serial.println("-----------------");
Serial.println("Total free heap: " + String(ESP.getFreeHeap()));
Serial.print("Connecting");
WiFi.begin("Wokwi-GUEST", "", 6);
while (WiFi.status() != WL_CONNECTED) {
delay(250);
Serial.print(".");
}
Serial.println(" done");
delay(1000);
Serial.print("Disconnecting");
WiFi.disconnect(true);
while (WiFi.status() == WL_CONNECTED) {
delay(250);
Serial.print(".");
}
WiFi.mode(WIFI_OFF);
Serial.println(" done");
Serial.println();
Serial.println();
}
}
Also see the reproducer at: https://github.com/lptr/esp-arduino-wifi-connect-loop-leak.
It is an ESP-IDF application using Arduino as a component.
It repeatedly connects and disconnects WiFi using WiFi.begin(...)
and WiFi.disconnect(true)
and WiFi.mode(WIFI_OFF)
. It measures the total heap and prints per-task allocations after each iteration.
Build with idf.py build
and flash it to an ESP32 board, or open the related diagram.json
with Wokwi and run the simulation.
Debug Message
Here's a few consecutive iterations' worth of logs from the reproducer:
-----------------
Total free heap: 295716
Task 0x0: Pre-Scheduler al CAP_8BIT: 3688, CAP_32BIT: 0
Task 0x3fcaafc4: main CAP_8BIT: 15380, CAP_32BIT: 0
Task 0x3fca85d8: ipc0 CAP_8BIT: 14288, CAP_32BIT: 0
Task 0x3fca8c54: ipc1 CAP_8BIT: 24, CAP_32BIT: 0
Task 0x3fcad834: tiT CAP_8BIT: 96, CAP_32BIT: 0
Task 0x3fcb2420: CAP_8BIT: 312, CAP_32BIT: 0
Task 0x3fcae934: sys_evt CAP_8BIT: 100, CAP_32BIT: 0
Task 0x3fcafab0: arduino_events CAP_8BIT: 100, CAP_32BIT: 0
Connecting..... done
Disconnecting done
====== Heap Trace: 5 records (256 capacity) ======
340 bytes (@ 0x3fcb2404, Internal) allocated CPU 0 ccount 0x73cb7e8c caller 0x4037e034:0x4037ec8f:0x4208a66c:0x42067a7d:0x42064536:0x4204a523:0x4204a983:0x4203b152:0x4200be53:0x4200bf41
16 bytes (@ 0x3fcac8f0, Internal) allocated CPU 1 ccount 0x82bd81f8 caller 0x4202b3f7:0x420174b6:0x42017521:0x4201de7c:0x4201df0c:0x4201e030:0x4202af55:0x4202b011:0x4037d7c5:
16 bytes (@ 0x3fcb7824, Internal) allocated CPU 1 ccount 0x82be6358 caller 0x4202b3f7:0x420174b6:0x42017521:0x4201de7c:0x4201df0c:0x4201e030:0x4202af55:0x4202b011:0x4037d7c5:
16 bytes (@ 0x3fcac8cc, Internal) allocated CPU 1 ccount 0x82beeacc caller 0x4202b3f7:0x420174b6:0x42017521:0x4201de7c:0x4201df0c:0x4201e030:0x4202af55:0x4202b011:0x4037d7c5:
16 bytes (@ 0x3fcb5ff8, Internal) allocated CPU 1 ccount 0x8a6d9da4 caller 0x4202b3f7:0x420174b6:0x42017521:0x4201de7c:0x4201df39:0x4202b8d5:0x4202d021:0x4202d035:0x42017b3e:0x42017bec
====== Heap Trace Summary ======
Mode: Heap Trace Leaks
404 bytes 'leaked' in trace (5 allocations)
records: 5 (256 capacity, 142 high water mark)
total allocations: 205
total frees: 235
================================
-----------------
Total free heap: 295680
Task 0x0: Pre-Scheduler al CAP_8BIT: 3688, CAP_32BIT: 0
Task 0x3fcaafc4: main CAP_8BIT: 15380, CAP_32BIT: 0
Task 0x3fca85d8: ipc0 CAP_8BIT: 14288, CAP_32BIT: 0
Task 0x3fca8c54: ipc1 CAP_8BIT: 24, CAP_32BIT: 0
Task 0x3fcad834: tiT CAP_8BIT: 112, CAP_32BIT: 0
Task 0x3fcb2420: CAP_8BIT: 312, CAP_32BIT: 0
Task 0x3fcae934: sys_evt CAP_8BIT: 100, CAP_32BIT: 0
Task 0x3fcafab0: arduino_events CAP_8BIT: 100, CAP_32BIT: 0
Connecting..... done
Disconnecting done
====== Heap Trace: 5 records (256 capacity) ======
340 bytes (@ 0x3fcb601c, Internal) allocated CPU 0 ccount 0x958bccac caller 0x4037e034:0x4037ec8f:0x4208a66c:0x42067a7d:0x42064536:0x4204a523:0x4204a983:0x4203b152:0x4200be53:0x4200bf41
16 bytes (@ 0x3fcac8f0, Internal) allocated CPU 1 ccount 0xa8e321f8 caller 0x4202b3f7:0x420174b6:0x42017521:0x4201de7c:0x4201df0c:0x4201e030:0x4202af55:0x4202b011:0x4037d7c5:
16 bytes (@ 0x3fcb7824, Internal) allocated CPU 1 ccount 0xa8e40358 caller 0x4202b3f7:0x420174b6:0x42017521:0x4201de7c:0x4201df0c:0x4201e030:0x4202af55:0x4202b011:0x4037d7c5:
16 bytes (@ 0x3fcac8cc, Internal) allocated CPU 1 ccount 0xa8e48acc caller 0x4202b3f7:0x420174b6:0x42017521:0x4201de7c:0x4201df0c:0x4201e030:0x4202af55:0x4202b011:0x4037d7c5:
16 bytes (@ 0x3fcb7ad8, Internal) allocated CPU 1 ccount 0xac2b50a4 caller 0x4202b3f7:0x420174b6:0x42017521:0x4201de7c:0x4201df39:0x4202b8d5:0x4202d021:0x4202d035:0x42017b3e:0x42017bec
====== Heap Trace Summary ======
Mode: Heap Trace Leaks
404 bytes 'leaked' in trace (5 allocations)
records: 5 (256 capacity, 142 high water mark)
total allocations: 208
total frees: 239
================================
Things to notice:
Total free heap
keeps decreasing,- the
tiT
task's allocation count keeps increasing, - the backtraces point to timeouts in the TCP/IP stack being allocated but not freed in some cases.
Here's the resolved backtrace of the many similar allocations reported by the heap leak detector:
mem_malloc
C:/Tools/Espressif/frameworks/esp-idf-v5.1.4/components/lwip/lwip/src/core/mem.c:209
do_memp_malloc_pool
C:/Tools/Espressif/frameworks/esp-idf-v5.1.4/components/lwip/lwip/src/core/memp.c:254
memp_malloc
C:/Tools/Espressif/frameworks/esp-idf-v5.1.4/components/lwip/lwip/src/core/memp.c:350 (discriminator 2)
sys_timeout_abs
C:/Tools/Espressif/frameworks/esp-idf-v5.1.4/components/lwip/lwip/src/core/timeouts.c:193
lwip_cyclic_timer
C:/Tools/Espressif/frameworks/esp-idf-v5.1.4/components/lwip/lwip/src/core/timeouts.c:265
sys_check_timeouts
C:/Tools/Espressif/frameworks/esp-idf-v5.1.4/components/lwip/lwip/src/core/timeouts.c:403
tcpip_timeouts_mbox_fetch
C:/Tools/Espressif/frameworks/esp-idf-v5.1.4/components/lwip/lwip/src/api/tcpip.c:111
tcpip_thread
C:/Tools/Espressif/frameworks/esp-idf-v5.1.4/components/lwip/lwip/src/api/tcpip.c:143
vPortTaskWrapper
C:/Tools/Espressif/frameworks/esp-idf-v5.1.4/components/freertos/FreeRTOS-Kernel/portable/xtensa/port.c:164
I have checked existing issues, online documentation and the Troubleshooting Guide
- I confirm I have checked existing issues, online documentation and Troubleshooting guide.