SenseCAP_Indicator_ESP32
SenseCAP_Indicator_ESP32 copied to clipboard
Memory leaks cause system to crash and/or openAI requests to fail in indicator_openai example
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