mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-07 06:34:34 +02:00
Merge branch 'feature/add_heap_info_per_task_example' into 'master'
Add Task Heap Tracking example See merge request espressif/esp-idf!7750
This commit is contained in:
@@ -117,6 +117,16 @@ Calls to :cpp:func:`heap_caps_check_integrity` may print errors relating to 0xFE
|
|||||||
- For free heap blocks, the checker expects to find all bytes set to 0xFE. Any other values indicate a use-after-free bug where free memory has been incorrectly overwritten.
|
- For free heap blocks, the checker expects to find all bytes set to 0xFE. Any other values indicate a use-after-free bug where free memory has been incorrectly overwritten.
|
||||||
- For allocated heap blocks, the behaviour is the same as for `Light Impact` mode. The canary bytes 0xABBA1234 and 0xBAAD5678 are checked at the head and tail of each allocated buffer, and any variation indicates a buffer overrun/underrun.
|
- For allocated heap blocks, the behaviour is the same as for `Light Impact` mode. The canary bytes 0xABBA1234 and 0xBAAD5678 are checked at the head and tail of each allocated buffer, and any variation indicates a buffer overrun/underrun.
|
||||||
|
|
||||||
|
.. _heap-task-tracking:
|
||||||
|
|
||||||
|
Heap Task Tracking
|
||||||
|
------------------
|
||||||
|
|
||||||
|
Heap Task Tracking can be used to get per task info for heap memory allocation.
|
||||||
|
Application has to specify the heap capabilities for which the heap allocation is to be tracked.
|
||||||
|
|
||||||
|
Example code is provided in :example:`system/heap_task_tracking`
|
||||||
|
|
||||||
.. _heap-tracing:
|
.. _heap-tracing:
|
||||||
|
|
||||||
Heap Tracing
|
Heap Tracing
|
||||||
|
6
examples/system/heap_task_tracking/CMakeLists.txt
Normal file
6
examples/system/heap_task_tracking/CMakeLists.txt
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
# The following lines of boilerplate have to be in your project's
|
||||||
|
# CMakeLists in this exact order for cmake to work correctly
|
||||||
|
cmake_minimum_required(VERSION 3.5)
|
||||||
|
|
||||||
|
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||||
|
project(heap_task_tracking)
|
9
examples/system/heap_task_tracking/Makefile
Normal file
9
examples/system/heap_task_tracking/Makefile
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
#
|
||||||
|
# This is a project Makefile. It is assumed the directory this Makefile resides in is a
|
||||||
|
# project subdirectory.
|
||||||
|
#
|
||||||
|
|
||||||
|
PROJECT_NAME := heap_task_tracking
|
||||||
|
|
||||||
|
include $(IDF_PATH)/make/project.mk
|
||||||
|
|
36
examples/system/heap_task_tracking/README.md
Normal file
36
examples/system/heap_task_tracking/README.md
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
# Heap Task Tracking Example
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
The example creates a task which allocates random amount of memory in each iteration and demonstrates use of internal API to get heap info on per task basis running in a system.
|
||||||
|
|
||||||
|
Heap task tracking feature has dependency on some of the internal heap debugging features (e.g. heap poisoning) which allows to store task control block in metadata of each heap block.
|
||||||
|
|
||||||
|
This adds small memory overhead on per heap block and hence this feature should be used for debugging purpose only.
|
||||||
|
|
||||||
|
### Configure the project
|
||||||
|
|
||||||
|
To change the `Heap Corruption Detection level`, open the project configuration menu (`idf.py menuconfig`).
|
||||||
|
|
||||||
|
Navigate to `Component config -> Heap memory debugging` menu. In `Heap corruption detection` menu select either "Light Impact" or "Comprehensive".
|
||||||
|
|
||||||
|
**Note:** Enabling “Comprehensive” detection has a substantial runtime performance impact.
|
||||||
|
|
||||||
|
### Build and Flash
|
||||||
|
|
||||||
|
Run `idf.py -p PORT flash monitor` to build and flash the project..
|
||||||
|
|
||||||
|
(To exit the serial monitor, type ``Ctrl-]``.)
|
||||||
|
|
||||||
|
See the [Getting Started Guide](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/index.html) for full steps to configure and use ESP-IDF to build projects.
|
||||||
|
|
||||||
|
## Example Output
|
||||||
|
|
||||||
|
```
|
||||||
|
Task: Pre-Scheduler allocs -> CAP_8BIT: 5360 CAP_32BIT: 0
|
||||||
|
Task: esp_timer -> CAP_8BIT: 1724 CAP_32BIT: 0
|
||||||
|
Task: ipc0 -> CAP_8BIT: 8316 CAP_32BIT: 0
|
||||||
|
Task: main -> CAP_8BIT: 3480 CAP_32BIT: 0
|
||||||
|
Task: ipc1 -> CAP_8BIT: 12 CAP_32BIT: 0
|
||||||
|
Task: example_task -> CAP_8BIT: 696 CAP_32BIT: 0
|
||||||
|
```
|
2
examples/system/heap_task_tracking/main/CMakeLists.txt
Normal file
2
examples/system/heap_task_tracking/main/CMakeLists.txt
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
idf_component_register(SRCS "heap_task_tracking_main.c"
|
||||||
|
INCLUDE_DIRS "")
|
5
examples/system/heap_task_tracking/main/component.mk
Normal file
5
examples/system/heap_task_tracking/main/component.mk
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
#
|
||||||
|
# "main" pseudo-component makefile.
|
||||||
|
#
|
||||||
|
# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.)
|
||||||
|
|
@@ -0,0 +1,77 @@
|
|||||||
|
/* Heap Task Tracking 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 "freertos/FreeRTOS.h"
|
||||||
|
#include "freertos/task.h"
|
||||||
|
#include "esp_heap_task_info.h"
|
||||||
|
#include "esp_log.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define MAX_TASK_NUM 20 // Max number of per tasks info that it can store
|
||||||
|
#define MAX_BLOCK_NUM 20 // Max number of per block info that it can store
|
||||||
|
|
||||||
|
static size_t s_prepopulated_num = 0;
|
||||||
|
static heap_task_totals_t s_totals_arr[MAX_TASK_NUM];
|
||||||
|
static heap_task_block_t s_block_arr[MAX_BLOCK_NUM];
|
||||||
|
|
||||||
|
static void esp_dump_per_task_heap_info(void)
|
||||||
|
{
|
||||||
|
heap_task_info_params_t heap_info = {0};
|
||||||
|
heap_info.caps[0] = MALLOC_CAP_8BIT; // Gets heap with CAP_8BIT capabilities
|
||||||
|
heap_info.mask[0] = MALLOC_CAP_8BIT;
|
||||||
|
heap_info.caps[1] = MALLOC_CAP_32BIT; // Gets heap info with CAP_32BIT capabilities
|
||||||
|
heap_info.mask[1] = MALLOC_CAP_32BIT;
|
||||||
|
heap_info.tasks = NULL; // Passing NULL captures heap info for all tasks
|
||||||
|
heap_info.num_tasks = 0;
|
||||||
|
heap_info.totals = s_totals_arr; // Gets task wise allocation details
|
||||||
|
heap_info.num_totals = &s_prepopulated_num;
|
||||||
|
heap_info.max_totals = MAX_TASK_NUM; // Maximum length of "s_totals_arr"
|
||||||
|
heap_info.blocks = s_block_arr; // Gets block wise allocation details. For each block, gets owner task, address and size
|
||||||
|
heap_info.max_blocks = MAX_BLOCK_NUM; // Maximum length of "s_block_arr"
|
||||||
|
|
||||||
|
heap_caps_get_per_task_info(&heap_info);
|
||||||
|
|
||||||
|
for (int i = 0 ; i < *heap_info.num_totals; i++) {
|
||||||
|
printf("Task: %s -> CAP_8BIT: %d CAP_32BIT: %d\n",
|
||||||
|
heap_info.totals[i].task ? pcTaskGetTaskName(heap_info.totals[i].task) : "Pre-Scheduler allocs" ,
|
||||||
|
heap_info.totals[i].size[0], // Heap size with CAP_8BIT capabilities
|
||||||
|
heap_info.totals[i].size[1]); // Heap size with CAP32_BIT capabilities
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void example_task(void *args)
|
||||||
|
{
|
||||||
|
uint32_t size = 0;
|
||||||
|
const char *TAG = "example_task";
|
||||||
|
while (1) {
|
||||||
|
/*
|
||||||
|
* Allocate random amount of memory for demonstration
|
||||||
|
*/
|
||||||
|
size = (esp_random() % 1000);
|
||||||
|
void *ptr = malloc(size);
|
||||||
|
if (ptr == NULL) {
|
||||||
|
ESP_LOGE(TAG, "Could not allocate heap memory");
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
esp_dump_per_task_heap_info();
|
||||||
|
free(ptr);
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(2000));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void app_main(void)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Create example task to demonstrate heap_task_tracking
|
||||||
|
*/
|
||||||
|
xTaskCreate(&example_task, "example_task", 3072, NULL, 5, NULL);
|
||||||
|
}
|
2
examples/system/heap_task_tracking/sdkconfig.defaults
Normal file
2
examples/system/heap_task_tracking/sdkconfig.defaults
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
CONFIG_HEAP_POISONING_LIGHT=y
|
||||||
|
CONFIG_HEAP_TASK_TRACKING=y
|
Reference in New Issue
Block a user