forked from espressif/esp-idf
fix(console): Memory leaks after deinit
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2016-2024 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2016-2025 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@@ -376,7 +376,18 @@ esp_err_t esp_console_register_help_command(void)
|
|||||||
.argtable = &help_args
|
.argtable = &help_args
|
||||||
};
|
};
|
||||||
return esp_console_cmd_register(&command);
|
return esp_console_cmd_register(&command);
|
||||||
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
esp_err_t esp_console_deregister_help_command(void)
|
||||||
|
{
|
||||||
|
free(help_args.help_cmd);
|
||||||
|
free(help_args.verbose_level);
|
||||||
|
free(help_args.end);
|
||||||
|
|
||||||
|
return esp_console_cmd_deregister("help");
|
||||||
|
}
|
||||||
|
|
||||||
esp_err_t esp_console_set_help_verbose_level(esp_console_help_verbose_level_e verbose_level)
|
esp_err_t esp_console_set_help_verbose_level(esp_console_help_verbose_level_e verbose_level)
|
||||||
{
|
{
|
||||||
/* legal verbose level sanity check */
|
/* legal verbose level sanity check */
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2016-2024 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2016-2025 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@@ -331,6 +331,15 @@ const char *esp_console_get_hint(const char *buf, int *color, int *bold);
|
|||||||
*/
|
*/
|
||||||
esp_err_t esp_console_register_help_command(void);
|
esp_err_t esp_console_register_help_command(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Deregister a 'help' command
|
||||||
|
*
|
||||||
|
* @return esp_err_t
|
||||||
|
* - ESP_OK on success
|
||||||
|
* - other on failure
|
||||||
|
*/
|
||||||
|
esp_err_t esp_console_deregister_help_command(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Set the verbose level for 'help' command
|
* @brief Set the verbose level for 'help' command
|
||||||
*
|
*
|
||||||
|
@@ -129,6 +129,22 @@ _exit:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void esp_console_common_deinit(esp_console_repl_com_t *repl_com)
|
||||||
|
{
|
||||||
|
/* Unregister the heap function to avoid memory leak, since it is created
|
||||||
|
* every time a console init is called. */
|
||||||
|
esp_err_t ret = esp_console_deregister_help_command();
|
||||||
|
assert(ret == ESP_OK);
|
||||||
|
|
||||||
|
/* unregister eventfd to avoid memory leaks, since it is created every time a
|
||||||
|
* console init is called */
|
||||||
|
(void)esp_vfs_eventfd_unregister();
|
||||||
|
|
||||||
|
/* free the history to avoid memory leak, since it is created
|
||||||
|
* every time a console init is called. */
|
||||||
|
linenoiseHistoryFree();
|
||||||
|
}
|
||||||
|
|
||||||
esp_err_t esp_console_start_repl(esp_console_repl_t *repl)
|
esp_err_t esp_console_start_repl(esp_console_repl_t *repl)
|
||||||
{
|
{
|
||||||
esp_err_t ret = ESP_OK;
|
esp_err_t ret = ESP_OK;
|
||||||
|
@@ -315,6 +315,8 @@ static esp_err_t esp_console_repl_uart_delete(esp_console_repl_t *repl)
|
|||||||
vSemaphoreDelete(repl_com->state_mux);
|
vSemaphoreDelete(repl_com->state_mux);
|
||||||
repl_com->state_mux = NULL;
|
repl_com->state_mux = NULL;
|
||||||
|
|
||||||
|
esp_console_common_deinit(&uart_repl->repl_com);
|
||||||
|
|
||||||
esp_console_deinit();
|
esp_console_deinit();
|
||||||
uart_vfs_dev_use_nonblocking(uart_repl->uart_channel);
|
uart_vfs_dev_use_nonblocking(uart_repl->uart_channel);
|
||||||
uart_driver_delete(uart_repl->uart_channel);
|
uart_driver_delete(uart_repl->uart_channel);
|
||||||
@@ -356,6 +358,8 @@ static esp_err_t esp_console_repl_usb_cdc_delete(esp_console_repl_t *repl)
|
|||||||
vSemaphoreDelete(repl_com->state_mux);
|
vSemaphoreDelete(repl_com->state_mux);
|
||||||
repl_com->state_mux = NULL;
|
repl_com->state_mux = NULL;
|
||||||
|
|
||||||
|
esp_console_common_deinit(&cdc_repl->repl_com);
|
||||||
|
|
||||||
esp_console_deinit();
|
esp_console_deinit();
|
||||||
free(cdc_repl);
|
free(cdc_repl);
|
||||||
_exit:
|
_exit:
|
||||||
@@ -395,6 +399,8 @@ static esp_err_t esp_console_repl_usb_serial_jtag_delete(esp_console_repl_t *rep
|
|||||||
vSemaphoreDelete(repl_com->state_mux);
|
vSemaphoreDelete(repl_com->state_mux);
|
||||||
repl_com->state_mux = NULL;
|
repl_com->state_mux = NULL;
|
||||||
|
|
||||||
|
esp_console_common_deinit(&usb_serial_jtag_repl->repl_com);
|
||||||
|
|
||||||
esp_console_deinit();
|
esp_console_deinit();
|
||||||
usb_serial_jtag_vfs_use_nonblocking();
|
usb_serial_jtag_vfs_use_nonblocking();
|
||||||
usb_serial_jtag_driver_uninstall();
|
usb_serial_jtag_driver_uninstall();
|
||||||
|
@@ -1265,6 +1265,7 @@ void linenoiseHistoryFree(void) {
|
|||||||
free(history);
|
free(history);
|
||||||
}
|
}
|
||||||
history = NULL;
|
history = NULL;
|
||||||
|
history_len = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This is the API call to add a new entry in the linenoise history.
|
/* This is the API call to add a new entry in the linenoise history.
|
||||||
|
@@ -47,6 +47,7 @@ typedef struct {
|
|||||||
void esp_console_repl_task(void *args);
|
void esp_console_repl_task(void *args);
|
||||||
|
|
||||||
esp_err_t esp_console_common_init(size_t max_cmdline_length, esp_console_repl_com_t *repl_com);
|
esp_err_t esp_console_common_init(size_t max_cmdline_length, esp_console_repl_com_t *repl_com);
|
||||||
|
void esp_console_common_deinit(esp_console_repl_com_t *repl_com);
|
||||||
esp_err_t esp_console_setup_prompt(const char *prompt, esp_console_repl_com_t *repl_com);
|
esp_err_t esp_console_setup_prompt(const char *prompt, esp_console_repl_com_t *repl_com);
|
||||||
esp_err_t esp_console_setup_history(const char *history_path,
|
esp_err_t esp_console_setup_history(const char *history_path,
|
||||||
uint32_t max_history_len,
|
uint32_t max_history_len,
|
||||||
|
@@ -10,7 +10,12 @@
|
|||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
|
||||||
// Some resources are lazy allocated (newlib locks) in the console code, the threshold is left for that case
|
// Some resources are lazy allocated (newlib locks) in the console code, the threshold is left for that case
|
||||||
#define TEST_MEMORY_LEAK_THRESHOLD (150)
|
#define TEST_MEMORY_LEAK_THRESHOLD_DEFAULT (150)
|
||||||
|
static int leak_threshold = TEST_MEMORY_LEAK_THRESHOLD_DEFAULT;
|
||||||
|
void set_leak_threshold(int threshold)
|
||||||
|
{
|
||||||
|
leak_threshold = threshold;
|
||||||
|
}
|
||||||
|
|
||||||
void setUp(void)
|
void setUp(void)
|
||||||
{
|
{
|
||||||
@@ -19,7 +24,8 @@ void setUp(void)
|
|||||||
|
|
||||||
void tearDown(void)
|
void tearDown(void)
|
||||||
{
|
{
|
||||||
unity_utils_evaluate_leaks_direct(TEST_MEMORY_LEAK_THRESHOLD);
|
unity_utils_evaluate_leaks_direct(leak_threshold);
|
||||||
|
leak_threshold = TEST_MEMORY_LEAK_THRESHOLD_DEFAULT;
|
||||||
}
|
}
|
||||||
|
|
||||||
void app_main(void)
|
void app_main(void)
|
||||||
|
@@ -154,8 +154,11 @@ TEST_CASE("esp console repl test", "[console][ignore]")
|
|||||||
vTaskDelay(pdMS_TO_TICKS(2000));
|
vTaskDelay(pdMS_TO_TICKS(2000));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern void set_leak_threshold(int threshold);
|
||||||
TEST_CASE("esp console repl deinit", "[console][ignore]")
|
TEST_CASE("esp console repl deinit", "[console][ignore]")
|
||||||
{
|
{
|
||||||
|
set_leak_threshold(400);
|
||||||
|
|
||||||
esp_console_repl_config_t repl_config = ESP_CONSOLE_REPL_CONFIG_DEFAULT();
|
esp_console_repl_config_t repl_config = ESP_CONSOLE_REPL_CONFIG_DEFAULT();
|
||||||
esp_console_dev_uart_config_t uart_config = ESP_CONSOLE_DEV_UART_CONFIG_DEFAULT();
|
esp_console_dev_uart_config_t uart_config = ESP_CONSOLE_DEV_UART_CONFIG_DEFAULT();
|
||||||
TEST_ESP_OK(esp_console_new_repl_uart(&uart_config, &repl_config, &s_repl));
|
TEST_ESP_OK(esp_console_new_repl_uart(&uart_config, &repl_config, &s_repl));
|
||||||
@@ -165,14 +168,17 @@ TEST_CASE("esp console repl deinit", "[console][ignore]")
|
|||||||
|
|
||||||
/* wait to make sure the task reaches linenoiseEdit function
|
/* wait to make sure the task reaches linenoiseEdit function
|
||||||
* and gets stuck in the select */
|
* and gets stuck in the select */
|
||||||
vTaskDelay(pdMS_TO_TICKS(500));
|
vTaskDelay(pdMS_TO_TICKS(10));
|
||||||
|
|
||||||
/* call the delete function, this returns only when the repl task terminated */
|
/* call the delete function, this returns only when the repl task terminated */
|
||||||
const esp_err_t res = s_repl->del(s_repl);
|
const esp_err_t res = s_repl->del(s_repl);
|
||||||
|
|
||||||
|
/* wait to make sure the task reaches linenoiseEdit function
|
||||||
|
* and gets stuck in the select */
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(10));
|
||||||
|
|
||||||
/* if this point is reached, the repl environment has been deleted successfully */
|
/* if this point is reached, the repl environment has been deleted successfully */
|
||||||
TEST_ASSERT(res == ESP_OK);
|
TEST_ASSERT(res == ESP_OK);
|
||||||
printf("-------------- %p\n", s_repl);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const esp_console_cmd_t cmd_a = {
|
static const esp_console_cmd_t cmd_a = {
|
||||||
|
Reference in New Issue
Block a user