To play with it a bit i made short test code with esp-idf and here all get really strange. Two almost the same pieces of code with malloc/calloc, both are without free allocated memory. Now its getting strange.
1. This code does not cause memory leak
Code: Select all
/* Hello World Example
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#include <stdio.h>
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "esp_spi_flash.h"
#include "esp_log.h"
#define TAG ""
void directTasksStatus()
{
UBaseType_t uxArraySize = uxTaskGetNumberOfTasks();
TaskStatus_t *pxTaskStatusArray;
uint32_t pulTotalRunTime = 0;
pxTaskStatusArray = (TaskStatus_t *)malloc(sizeof(TaskStatus_t) * uxArraySize);
uxTaskGetSystemState(&pxTaskStatusArray[0], uxArraySize, &pulTotalRunTime);
for (int i = 0; i < uxArraySize; i++)
{
ESP_LOGI(TAG, "[%2d] %*s => stack remaining: %*d", i, 20, pxTaskStatusArray[i].pcTaskName, 4, pxTaskStatusArray[i].usStackHighWaterMark);
}
heap_caps_print_heap_info(MALLOC_CAP_DEFAULT);
if (!heap_caps_check_integrity_all(true))
{
heap_caps_dump_all();
// heap_caps_print_heap_info(MALLOC_CAP_DEFAULT);
}
ESP_LOGI(TAG, "directTasksStatus: stack remaining: %d", uxTaskGetStackHighWaterMark(NULL));
free(pxTaskStatusArray);
}
static void test_task(void* p)
{
while(1)
{
// printf("malloc\n");
void* prv = calloc(1, 10000);
uint32_t free_heap_size = 0, min_free_heap_size = 0;
free_heap_size = esp_get_free_heap_size();
min_free_heap_size = esp_get_minimum_free_heap_size();
ESP_LOGI(TAG, "directTasksStatus: free heap size = %d \t min_free_heap_size = %d", free_heap_size, min_free_heap_size);
vTaskDelay(1000);
}
}
TaskHandle_t handle1;
TaskHandle_t handle2;
TaskHandle_t handle3;
TaskHandle_t handle4;
void app_main(void)
{
while(1){
xTaskCreate(test_task, "test", 4 * 1024, NULL, 5, &handle1);
xTaskCreate(test_task, "test", 4 * 1024, NULL, 5, &handle2);
xTaskCreate(test_task, "test", 4 * 1024, NULL, 5, &handle3);
xTaskCreate(test_task, "test", 4 * 1024, NULL, 5, &handle4);
directTasksStatus();
vTaskDelay(1000);
vTaskDelete(handle1);
vTaskDelete(handle2);
vTaskDelete(handle3);
vTaskDelete(handle4);
if(handle1) printf("task1 stack: %d\n", uxTaskGetStackHighWaterMark(handle1));
if(handle2) printf("task2 stack: %d\n", uxTaskGetStackHighWaterMark(handle2));
if(handle3) printf("task3 stack: %d\n", uxTaskGetStackHighWaterMark(handle3));
if(handle4) printf("task4 stack: %d\n", uxTaskGetStackHighWaterMark(handle4));
vTaskDelay(1000);
directTasksStatus();
vTaskDelay(1000);
}
}
Code: Select all
/* Hello World Example
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#include <stdio.h>
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "esp_spi_flash.h"
#include "esp_log.h"
#define TAG ""
void directTasksStatus()
{
UBaseType_t uxArraySize = uxTaskGetNumberOfTasks();
TaskStatus_t *pxTaskStatusArray;
uint32_t pulTotalRunTime = 0;
pxTaskStatusArray = (TaskStatus_t *)malloc(sizeof(TaskStatus_t) * uxArraySize);
uxTaskGetSystemState(&pxTaskStatusArray[0], uxArraySize, &pulTotalRunTime);
for (int i = 0; i < uxArraySize; i++)
{
ESP_LOGI(TAG, "[%2d] %*s => stack remaining: %*d", i, 20, pxTaskStatusArray[i].pcTaskName, 4, pxTaskStatusArray[i].usStackHighWaterMark);
}
heap_caps_print_heap_info(MALLOC_CAP_DEFAULT);
if (!heap_caps_check_integrity_all(true))
{
heap_caps_dump_all();
// heap_caps_print_heap_info(MALLOC_CAP_DEFAULT);
}
ESP_LOGI(TAG, "directTasksStatus: stack remaining: %d", uxTaskGetStackHighWaterMark(NULL));
free(pxTaskStatusArray);
}
static void test_task(void* p)
{
while(1)
{
// printf("malloc\n");
void* prv = calloc(1, 10000);
uint32_t free_heap_size = 0, min_free_heap_size = 0;
free_heap_size = esp_get_free_heap_size();
min_free_heap_size = esp_get_minimum_free_heap_size();
if( prv)ESP_LOGI(TAG, "directTasksStatus: free heap size = %d \t min_free_heap_size = %d", free_heap_size, min_free_heap_size);
vTaskDelay(1000);
}
}
TaskHandle_t handle1;
TaskHandle_t handle2;
TaskHandle_t handle3;
TaskHandle_t handle4;
void app_main(void)
{
while(1){
xTaskCreate(test_task, "test", 4 * 1024, NULL, 5, &handle1);
xTaskCreate(test_task, "test", 4 * 1024, NULL, 5, &handle2);
xTaskCreate(test_task, "test", 4 * 1024, NULL, 5, &handle3);
xTaskCreate(test_task, "test", 4 * 1024, NULL, 5, &handle4);
directTasksStatus();
vTaskDelay(1000);
vTaskDelete(handle1);
vTaskDelete(handle2);
vTaskDelete(handle3);
vTaskDelete(handle4);
if(handle1) printf("task1 stack: %d\n", uxTaskGetStackHighWaterMark(handle1));
if(handle2) printf("task2 stack: %d\n", uxTaskGetStackHighWaterMark(handle2));
if(handle3) printf("task3 stack: %d\n", uxTaskGetStackHighWaterMark(handle3));
if(handle4) printf("task4 stack: %d\n", uxTaskGetStackHighWaterMark(handle4));
vTaskDelay(1000);
directTasksStatus();
vTaskDelay(1000);
}
}
Code: Select all
if( prv)ESP_LOGI(TAG, "directTasksStatus: free heap size = %d \t min_free_heap_size = %d", free_heap_size, min_free_heap_size);