Seeed-Solution / SenseCAP_Indicator_ESP32

SenseCAP Indicator SDK.
https://wiki.seeedstudio.com/SenseCAP_Indicator_How_To_Flash_The_Default_Firmware/#ESP-IDF
Apache License 2.0
39 stars 30 forks source link

Memory leaks cause system to crash and/or openAI requests to fail in indicator_openai example #52

Closed samprager closed 4 months ago

samprager commented 7 months ago

When I tried to build/run the indicator_openai example, (built with esp-idf v5.1.1), I found that multiple Chat GPT requests or DALL-E requests via mbedtls_send_then_recv() cause heap memory leaks so that eventually mbedtls_ssl_setup() will return the error:

**E (58463) openai: mbedtls_ssl_setup returned -0x7f00**

Additionally, in this case the goto exit; will result in these functions calls:

mbedtls_ssl_session_reset(&ssl);
mbedtls_net_free( &server_fd );

which cause the system to crash if/when mbedtls_ssl_setup() fails.

We can see that with each call to mbedtls_send_then_recv(), the free internal heap size reported by:

esp_get_free_internal_heap_size()

decreases continuously each time a request is sent to either Dall-E or Chat-GPT until there is not enough memory for mbedtls_ssl_setup(). I saw this issue on both the main branch (895d82a) as well as the tags/v1.03 branch.

It looks like mbed TLS resources are not being torn down in accordance with the documentation:

https://mbed-tls.readthedocs.io/en/latest/kb/how-to/mbedtls-tutorial/#teardown

This patch gets rid of the memory leaks and prevents the system from crashing in the event that mbedtls_ssl_setup() returns an error:

diff --git a/examples/indicator_openai/main/model/indicator_openai.c b/examples/indicator_openai/main/model/indicator_openai.c
index bdcfbda..4399500 100644
--- a/examples/indicator_openai/main/model/indicator_openai.c
+++ b/examples/indicator_openai/main/model/indicator_openai.c
@@ -55,13 +55,16 @@ static int mbedtls_send_then_recv(char *p_server, char *p_port, char *p_tx,
     mbedtls_ssl_config conf;
     mbedtls_net_context server_fd;

+    bool fd_initialized=false;
+    bool session_initialized=false;
+
     memset(&entropy,0, sizeof(entropy) );
     memset(&ctr_drbg,0, sizeof(ctr_drbg) );
     memset(&ssl,0, sizeof(ssl) );
     memset(&cacert,0, sizeof(cacert) );
     memset(&conf,0, sizeof(conf) );
     memset(&server_fd,0, sizeof(server_fd) );

     mbedtls_ssl_init(&ssl);
     mbedtls_x509_crt_init(&cacert);
     mbedtls_ctr_drbg_init(&ctr_drbg);
@@ -121,6 +124,7 @@ static int mbedtls_send_then_recv(char *p_server, char *p_port, char *p_tx,
     }

     mbedtls_net_init(&server_fd);
+    fd_initialized=true;

     ESP_LOGI(TAG, "Connecting to %s:%s...", p_server, p_port);

@@ -130,6 +134,7 @@ static int mbedtls_send_then_recv(char *p_server, char *p_port, char *p_tx,
         ESP_LOGE(TAG, "mbedtls_net_connect returned -%x", -ret);
         goto exit;
     }
+    session_initialized = true;

     ESP_LOGI(TAG, "Connected.");

@@ -234,8 +239,17 @@ static int mbedtls_send_then_recv(char *p_server, char *p_port, char *p_tx,

     mbedtls_ssl_close_notify(&ssl);
 exit:
-    mbedtls_ssl_session_reset(&ssl);
-    mbedtls_net_free(&server_fd);
+    if (session_initialized) {
+       mbedtls_ssl_session_reset(&ssl);
+    }
+    if (fd_initialized) {
+       mbedtls_net_free( &server_fd );
+    }
+    mbedtls_x509_crt_free( &cacert );
+    mbedtls_ssl_free( &ssl );
+    mbedtls_ssl_config_free( &conf );
+    mbedtls_ctr_drbg_free( &ctr_drbg );
+    mbedtls_entropy_free( &entropy );

     if (ret != 0)
     {

This fixes the issue and multiple openAI requests can be made. I'm not sure if this issue is also present in other examples since I've only looked at the indicator_openai example.

Additionally, in order to get the example to work properly I had to add the following back into indicator_openai/sdkconfig.defaults:

CONFIG_SPIRAM_TRY_ALLOCATE_WIFI_LWIP=y
CONFIG_LV_USE_PNG=y
Love4yzp commented 5 months ago

For those who want to integrate with OpenAI app, there is an API provided by espressif: https://github.com/espressif/esp-iot-solution/tree/7dd88d70fb494867fb91776b5f8b8dbbbc29e758/components/openai