Description
Answers checklist.
- I have read the documentation ESP-IDF Programming Guide and the issue is not addressed there.
- I have updated my IDF branch (master or release) to the latest version and checked that the issue is present there.
- I have searched the issue tracker for a similar issue and not found a similar issue.
IDF version.
v5.2.3, and master (v5.4-dev-4076-gce6085349f)
Espressif SoC revision.
ESP32-S2
Operating System used.
Linux
How did you build your project?
Command line with idf.py
If you are using Windows, please specify command line type.
None
Development Kit.
ESP32-S2-Saola
Power Supply used.
USB
What is the expected behavior?
heap_caps_malloc(n, MALLOC_CAP_EXEC) should return NULL or memory which is executable.
What is the actual behavior?
It seems RTC FAST memory is added to the executable heap space but the address returned is the Data Bus mapping not the Instruction Bus mapping.
Steps to reproduce.
- Copy the following C code into an example:
#include <stdio.h>
#include <inttypes.h>
#include "esp_memory_utils.h"
#include "esp_heap_caps.h"
void leak_pointer(void * arg)
{
// Keep the compiler happy by leaking memory to here
}
void app_main(void)
{
heap_caps_print_heap_info(MALLOC_CAP_EXEC);
while (1) {
void *p = heap_caps_malloc(2048, MALLOC_CAP_EXEC);
printf("Alloced %p\n", p);
if (p == NULL) {
printf("Out of executable RAM, woohoo!\n");
return;
}
if (!esp_ptr_executable(p)) {
printf("Got non-executable pointer back :(\n");
return;
}
leak_pointer(p);
}
}
idf.py set-target esp32s2
idf.py menuconfig
and setESP_SYSTEM_MEMPROT_FEATURE
ton
(to allow executable heap)idf.py flash monitor
Debug Logs.
I (23) boot: ESP-IDF v5.4-dev-4076-gce6085349f-dirty 2nd stage bootloader
I (24) boot: compile time Nov 6 2024 15:02:57
I (24) boot: chip revision: v0.0
I (26) boot: efuse block revision: v0.1
I (30) boot.esp32s2: SPI Speed : 80MHz
I (34) boot.esp32s2: SPI Mode : DIO
I (38) boot.esp32s2: SPI Flash Size : 2MB
I (41) boot: Enabling RNG early entropy source...
I (46) boot: Partition Table:
I (48) boot: ## Label Usage Type ST Offset Length
I (55) boot: 0 nvs WiFi data 01 02 00009000 00006000
I (61) boot: 1 phy_init RF data 01 01 0000f000 00001000
I (68) boot: 2 factory factory app 00 00 00010000 00100000
I (74) boot: End of partition table
I (78) esp_image: segment 0: paddr=00010020 vaddr=3f000020 size=08ef8h ( 36600) map
I (92) esp_image: segment 1: paddr=00018f20 vaddr=3ff9e010 size=0001ch ( 28) load
I (93) esp_image: segment 2: paddr=00018f44 vaddr=3ffbf950 size=01bf0h ( 7152) load
I (101) esp_image: segment 3: paddr=0001ab3c vaddr=40024000 size=054dch ( 21724) load
I (113) esp_image: segment 4: paddr=00020020 vaddr=40080020 size=13304h ( 78596) map
I (130) esp_image: segment 5: paddr=0003332c vaddr=400294dc size=06468h ( 25704) load
I (142) boot: Loaded app from partition at offset 0x10000
I (142) boot: Disabling RNG early entropy source...
I (152) cache: Instruction cache : size 8KB, 4Ways, cache line size 32Byte
I (152) cache: Data cache : size 8KB, 4Ways, cache line size 32Byte
I (167) cpu_start: Unicore app
I (174) cpu_start: Pro cpu start user code
I (174) cpu_start: cpu freq: 160000000 Hz
I (174) app_init: Application information:
I (174) app_init: Project name: hello_world
I (178) app_init: App version: v5.4-dev-4076-gce6085349f-dirty
I (184) app_init: Compile time: Nov 6 2024 15:03:00
I (189) app_init: ELF file SHA256: bea6b51e6...
I (194) app_init: ESP-IDF: v5.4-dev-4076-gce6085349f-dirty
I (200) efuse_init: Min chip rev: v0.0
I (204) efuse_init: Max chip rev: v1.99
I (208) efuse_init: Chip rev: v0.0
I (212) heap_init: Initializing. RAM available for dynamic allocation:
I (218) heap_init: At 3FFC1D58 len 0003A2A8 (232 KiB): RAM
I (223) heap_init: At 3FFFC000 len 00003A10 (14 KiB): RAM
I (228) heap_init: At 3FF9E02C len 00001FBC (7 KiB): RTCRAM
I (234) spi_flash: detected chip: generic
I (237) spi_flash: flash io: dio
W (240) spi_flash: Detected size(4096k) larger than the size in the binary image header(2048k). Using the size in the binary image header.
I (253) main_task: Started on CPU0
I (253) main_task: Calling app_main()
Heap summary for capabilities 0x00000001:
At 0x3ffc1d58 len 238248 free 228728 allocated 8420 min_free 228728
largest_free_block 221184 alloc_blocks 40 free_blocks 1 total_blocks 41
At 0x3fffc000 len 14864 free 14448 allocated 0 min_free 14448
largest_free_block 14336 alloc_blocks 0 free_blocks 1 total_blocks 1
At 0x3ff9e02c len 8124 free 7744 allocated 0 min_free 7744
largest_free_block 7680 alloc_blocks 0 free_blocks 1 total_blocks 1
Totals:
free 250920 allocated 8420 min_free 250920 largest_free_block 221184
Alloced 0x40034290
Alloced 0x40034b14
Alloced 0x40035398
... Skip many similar lines out of output
Alloced 0x4006e5b8
Alloced 0x4006eebc
Alloced 0x3ff9e1ac
Got non-executable pointer back :(
I (493) main_task: Returned from app_main()
Done
More Information.
While running the test program above on other SoCs to see if the problem is only on ESP32-S2 I noticed this output with original ESP32 running on v5.2.3 and the master branch:
... Skip early output
I (191) app_init: Application information:
I (194) app_init: Project name: hello_world
I (199) app_init: App version: v5.4-dev-4076-gce6085349f-dirty
I (206) app_init: Compile time: Nov 6 2024 15:01:23
I (212) app_init: ELF file SHA256: 9b90875fc...
I (217) app_init: ESP-IDF: v5.4-dev-4076-gce6085349f-dirty
I (224) efuse_init: Min chip rev: v0.0
I (229) efuse_init: Max chip rev: v3.99
I (234) efuse_init: Chip rev: v3.0
... Skip lines of expected output
Alloced 0x4009e7b0
Alloced 0x4009efb4
Alloced 0x4009f7b8
Alloced 0x400bf21c
Got non-executable pointer back :(
I (420) main_task: Returned from app_main()
Done
It seems like esp_ptr_executable(0x400bf21c)
is false
. According to the TRM this is the "Remap" region of "Internal SRAM 1", so I'm not sure if the bug here is that this address should not be returned for MALLOC_CAP_EXEC
or that esp_ptr_executable()
is returning false for an executable address. I can open a second issue for this if it is helpful.