From cf95ea40d48197ed9c738b98a1a86c2ed6d4e338 Mon Sep 17 00:00:00 2001 From: Felipe Neves Date: Mon, 11 Nov 2019 11:34:37 +0800 Subject: [PATCH 1/8] heap/test_leak: changed requested memory on leak checks to match the threshold --- components/heap/test/test_leak.c | 14 +++++++------- components/heap/test/test_malloc_caps.c | 2 +- components/heap/test/test_realloc.c | 2 +- .../components/test_utils/test_runner.c | 4 ++++ 4 files changed, 13 insertions(+), 9 deletions(-) diff --git a/components/heap/test/test_leak.c b/components/heap/test/test_leak.c index 1153fe1bc9..0144cd937e 100644 --- a/components/heap/test/test_leak.c +++ b/components/heap/test/test_leak.c @@ -18,18 +18,18 @@ static char* check_calloc(int size) TEST_CASE("Check for leaks (no leak)", "[heap]") { - char *arr = check_calloc(7000); + char *arr = check_calloc(1000); free(arr); } TEST_CASE("Check for leaks (leak)", "[heap][ignore]") { - check_calloc(7000); + check_calloc(1000); } TEST_CASE("Not check for leaks", "[heap][leaks]") { - check_calloc(7000); + check_calloc(1000); } TEST_CASE("Set a leak level = 7016", "[heap][leaks=7016]") @@ -39,7 +39,7 @@ TEST_CASE("Set a leak level = 7016", "[heap][leaks=7016]") static void test_fn(void) { - check_calloc(7000); + check_calloc(1000); } TEST_CASE_MULTIPLE_STAGES("Not check for leaks in MULTIPLE_STAGES mode", "[heap][leaks]", test_fn, test_fn, test_fn); @@ -48,13 +48,13 @@ TEST_CASE_MULTIPLE_STAGES("Check for leaks in MULTIPLE_STAGES mode (leak)", "[he static void test_fn2(void) { - check_calloc(7000); + check_calloc(1000); esp_restart(); } static void test_fn3(void) { - check_calloc(7000); + check_calloc(1000); } -TEST_CASE_MULTIPLE_STAGES_ESP32("Check for leaks in MULTIPLE_STAGES mode (manual reset)", "[heap][leaks][reset=SW_CPU_RESET, SW_CPU_RESET]", test_fn2, test_fn2, test_fn3); +TEST_CASE_MULTIPLE_STAGES("Check for leaks in MULTIPLE_STAGES mode (manual reset)", "[heap][leaks][reset=SW_CPU_RESET, SW_CPU_RESET]", test_fn2, test_fn2, test_fn3); diff --git a/components/heap/test/test_malloc_caps.c b/components/heap/test/test_malloc_caps.c index 9fdbec5716..74c8084771 100644 --- a/components/heap/test/test_malloc_caps.c +++ b/components/heap/test/test_malloc_caps.c @@ -11,7 +11,7 @@ #include #include -TEST_CASE_ESP32("Capabilities allocator test", "[heap]") +TEST_CASE("Capabilities allocator test", "[heap]") { char *m1, *m2[10]; int x; diff --git a/components/heap/test/test_realloc.c b/components/heap/test/test_realloc.c index 6781c2af3f..290ee3da6e 100644 --- a/components/heap/test/test_realloc.c +++ b/components/heap/test/test_realloc.c @@ -22,7 +22,7 @@ TEST_CASE("realloc shrink buffer in place", "[heap]") #endif -TEST_CASE_ESP32("realloc move data to a new heap type", "[heap]") +TEST_CASE("realloc move data to a new heap type", "[heap]") { const char *test = "I am some test content to put in the heap"; char buf[64]; diff --git a/tools/unit-test-app/components/test_utils/test_runner.c b/tools/unit-test-app/components/test_utils/test_runner.c index fc09d5a450..d6cdef9f4b 100644 --- a/tools/unit-test-app/components/test_utils/test_runner.c +++ b/tools/unit-test-app/components/test_utils/test_runner.c @@ -87,6 +87,10 @@ void setUp(void) static void check_leak(size_t before_free, size_t after_free, const char *type) { + printf("MALLOC_CAP_%s leak: Leak threshold is: %u \n", + type, + critical_leak_threshold); + if (before_free <= after_free) { return; } From ecc4955c6820bc3a460357f256be5e8da482288e Mon Sep 17 00:00:00 2001 From: Felipe Neves Date: Mon, 11 Nov 2019 12:57:13 +0800 Subject: [PATCH 2/8] heap/test_malloc_caps: changed malloc caps test to deal with esp32 and esp32s2 memory differencies. --- components/heap/test/test_malloc_caps.c | 73 ++++++++++++++++--------- 1 file changed, 47 insertions(+), 26 deletions(-) diff --git a/components/heap/test/test_malloc_caps.c b/components/heap/test/test_malloc_caps.c index 74c8084771..54a0b3f7fd 100644 --- a/components/heap/test/test_malloc_caps.c +++ b/components/heap/test/test_malloc_caps.c @@ -24,7 +24,7 @@ TEST_CASE("Capabilities allocator test", "[heap]") free8start = heap_caps_get_free_size(MALLOC_CAP_8BIT); free32start = heap_caps_get_free_size(MALLOC_CAP_32BIT); printf("Free 8bit-capable memory (start): %dK, 32-bit capable memory %dK\n", free8start, free32start); - TEST_ASSERT(free32start>free8start); + TEST_ASSERT(free32start >= free8start); printf("Allocating 10K of 8-bit capable RAM\n"); m1= heap_caps_malloc(10*1024, MALLOC_CAP_8BIT); @@ -44,39 +44,60 @@ TEST_CASE("Capabilities allocator test", "[heap]") size_t free_iram = heap_caps_get_free_size(MALLOC_CAP_INTERNAL) - heap_caps_get_free_size(MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL); size_t alloc32 = MIN(free_iram / 2, 10*1024) & (~3); - printf("Freeing; allocating %u bytes of 32K-capable RAM\n", alloc32); - m1 = heap_caps_malloc(alloc32, MALLOC_CAP_32BIT); - printf("--> %p\n", m1); - //Check that we got IRAM back - TEST_ASSERT((((int)m1)&0xFF000000)==0x40000000); - free8 = heap_caps_get_free_size(MALLOC_CAP_8BIT); - free32 = heap_caps_get_free_size(MALLOC_CAP_32BIT); - printf("Free 8bit-capable memory (after 32-bit): %dK, 32-bit capable memory %dK\n", free8, free32); - //Only 32-bit should have gone down by alloc32: 32-bit isn't necessarily 8bit capable - TEST_ASSERT(free32<(free32start-alloc32)); - TEST_ASSERT(free8==free8start); - free(m1); + if(free_iram) { + printf("Freeing; allocating %u bytes of 32K-capable RAM\n", alloc32); + m1 = heap_caps_malloc(alloc32, MALLOC_CAP_32BIT); + printf("--> %p\n", m1); + //Check that we got IRAM back + TEST_ASSERT((((int)m1)&0xFF000000)==0x40000000); + free8 = heap_caps_get_free_size(MALLOC_CAP_8BIT); + free32 = heap_caps_get_free_size(MALLOC_CAP_32BIT); + printf("Free 8bit-capable memory (after 32-bit): %dK, 32-bit capable memory %dK\n", free8, free32); + //Only 32-bit should have gone down by alloc32: 32-bit isn't necessarily 8bit capable + TEST_ASSERT(free32<(free32start-alloc32)); + TEST_ASSERT(free8==free8start); + free(m1); + } else { + printf("This platform has no 32-bit only capable RAM, jumping to next test \n"); + } printf("Allocating impossible caps\n"); m1= heap_caps_malloc(10*1024, MALLOC_CAP_8BIT|MALLOC_CAP_EXEC); printf("--> %p\n", m1); TEST_ASSERT(m1==NULL); - printf("Testing changeover iram -> dram"); - // priorities will exhaust IRAM first, then start allocating from DRAM - for (x=0; x<10; x++) { - m2[x]= heap_caps_malloc(alloc32, MALLOC_CAP_32BIT); - printf("--> %p\n", m2[x]); + + if(free_iram) { + printf("Testing changeover iram -> dram"); + // priorities will exhaust IRAM first, then start allocating from DRAM + for (x=0; x<10; x++) { + m2[x]= heap_caps_malloc(alloc32, MALLOC_CAP_32BIT); + printf("--> %p\n", m2[x]); + } + TEST_ASSERT((((int)m2[0])&0xFF000000)==0x40000000); + TEST_ASSERT((((int)m2[9])&0xFF000000)==0x3F000000); + + } else { + printf("This platform has no IRAM-only so changeover will never occur, jumping to next test\n"); } - TEST_ASSERT((((int)m2[0])&0xFF000000)==0x40000000); - TEST_ASSERT((((int)m2[9])&0xFF000000)==0x3F000000); + printf("Test if allocating executable code still gives IRAM, even with dedicated IRAM region depleted\n"); - // (the allocation should come from D/IRAM) - free_iram = heap_caps_get_free_size(MALLOC_CAP_EXEC); - m1= heap_caps_malloc(MIN(free_iram / 2, 10*1024), MALLOC_CAP_EXEC); - printf("--> %p\n", m1); - TEST_ASSERT((((int)m1)&0xFF000000)==0x40000000); + if(free_iram) { + // (the allocation should come from D/IRAM) + free_iram = heap_caps_get_free_size(MALLOC_CAP_EXEC); + m1= heap_caps_malloc(MIN(free_iram / 2, 10*1024), MALLOC_CAP_EXEC); + printf("--> %p\n", m1); + TEST_ASSERT((((int)m1)&0xFF000000)==0x40000000); + for (x=0; x<10; x++) free(m2[x]); + + } else { + // (the allocation should come from D/IRAM) + free_iram = heap_caps_get_free_size(MALLOC_CAP_EXEC); + m1= heap_caps_malloc(MIN(free_iram / 2, 10*1024), MALLOC_CAP_EXEC); + printf("--> %p\n", m1); + TEST_ASSERT((((int)m1)&0xFF000000)==0x40000000); + } + free(m1); - for (x=0; x<10; x++) free(m2[x]); printf("Done.\n"); } From 4a392932f1909364e606fa893cea3ce14e0c8122 Mon Sep 17 00:00:00 2001 From: Felipe Neves Date: Tue, 12 Nov 2019 14:01:27 +0800 Subject: [PATCH 3/8] heap/heap_caps: added special case for esp32s2 when handling memory allocated (and aliased) from IRAM --- components/heap/heap_caps.c | 14 +++++++++++++- components/heap/multi_heap_poisoning.c | 14 ++++++++++++++ components/heap/test/test_realloc.c | 3 +-- 3 files changed, 28 insertions(+), 3 deletions(-) diff --git a/components/heap/heap_caps.c b/components/heap/heap_caps.c index 9e2ddd3a41..28cb7bf4d1 100644 --- a/components/heap/heap_caps.c +++ b/components/heap/heap_caps.c @@ -107,6 +107,7 @@ IRAM_ATTR void *heap_caps_malloc( size_t size, uint32_t caps ) //we need to 'invert' it (lowest address in DRAM == highest address in IRAM and vice-versa) and //add a pointer to the DRAM equivalent before the address we're going to return. ret = multi_heap_malloc(heap->heap, size + 4); // int overflow checked above + if (ret != NULL) { return dram_alloc_to_iram_addr(ret, size + 4); // int overflow checked above } @@ -287,8 +288,18 @@ IRAM_ATTR void *heap_caps_realloc( void *ptr, size_t size, int caps) return NULL; } - heap_t *heap = find_containing_heap(ptr); +#if CONFIG_IDF_TARGET_ESP32S2BETA + //On esp32s2 the pointer to heap may be aliased, we need to + //recover it before to manage a new allocation: + if(esp_ptr_in_diram_iram((void *)ptr)) { + //pointer must be already aliased, otherwise just ignore this part: + uint32_t *dram_addr = (uint32_t *)ptr; + ptr = (void *)dram_addr[-1]; + //printf("[HEAP_CAPS_MALLOC]: obtained pointer that was aliased: %p \n", (void *)ptr); + } +#endif + heap_t *heap = find_containing_heap(ptr); assert(heap != NULL && "realloc() pointer is outside heap areas"); // are the existing heap's capabilities compatible with the @@ -308,6 +319,7 @@ IRAM_ATTR void *heap_caps_realloc( void *ptr, size_t size, int caps) // in a different heap with requested capabilities. void *new_p = heap_caps_malloc(size, caps); if (new_p != NULL) { + size_t old_size = multi_heap_get_allocated_size(heap->heap, ptr); assert(old_size > 0); memcpy(new_p, ptr, MIN(size, old_size)); diff --git a/components/heap/multi_heap_poisoning.c b/components/heap/multi_heap_poisoning.c index a896043abb..559ad18d2e 100644 --- a/components/heap/multi_heap_poisoning.c +++ b/components/heap/multi_heap_poisoning.c @@ -21,6 +21,7 @@ #include #include #include "multi_heap_internal.h" +#include "heap_private.h" /* Note: Keep platform-specific parts in this header, this source file should depend on libc only */ @@ -268,7 +269,20 @@ void *multi_heap_realloc(multi_heap_handle_t heap, void *p, size_t size) new_head = multi_heap_malloc_impl(heap, size + POISON_OVERHEAD); if (new_head != NULL) { result = poison_allocated_region(new_head, size); + +#if CONFIG_IDF_TARGET_ESP32S2BETA + //We may need to deal with aliased heap pointers. here too, + //mainly because the heap canary is located before the + //the slot reserved to preserve original DRAM address + //so the original user data is actually p + 4 ahead : + if(esp_ptr_in_diram_dram((void *)p)) { + memcpy(result, p + sizeof(intptr_t), MIN(size, orig_alloc_size)); + } else { + memcpy(result, p , MIN(size, orig_alloc_size)); + } +#else memcpy(result, p, MIN(size, orig_alloc_size)); +#endif multi_heap_free(heap, p); } #endif diff --git a/components/heap/test/test_realloc.c b/components/heap/test/test_realloc.c index 290ee3da6e..763cddab62 100644 --- a/components/heap/test/test_realloc.c +++ b/components/heap/test/test_realloc.c @@ -31,7 +31,6 @@ TEST_CASE("realloc move data to a new heap type", "[heap]") char *a = malloc(64); memcpy(a, buf, 64); - // move data from 'a' to IRAM char *b = heap_caps_realloc(a, 64, MALLOC_CAP_EXEC); TEST_ASSERT_NOT_NULL(b); @@ -40,7 +39,7 @@ TEST_CASE("realloc move data to a new heap type", "[heap]") TEST_ASSERT_EQUAL_HEX32_ARRAY(buf, b, 64/sizeof(uint32_t)); // Move data back to DRAM - char *c = heap_caps_realloc(b, 48, MALLOC_CAP_8BIT); + char *c = heap_caps_realloc(b, 48, MALLOC_CAP_8BIT); TEST_ASSERT_NOT_NULL(c); TEST_ASSERT_NOT_EQUAL(b, c); TEST_ASSERT(heap_caps_check_integrity(MALLOC_CAP_INVALID, true)); From d9ab33118e667db7ab6e1067bed56049d47b5203 Mon Sep 17 00:00:00 2001 From: Felipe Neves Date: Wed, 13 Nov 2019 09:32:33 +0800 Subject: [PATCH 4/8] heap/multi_heap_poisoning: include heap_private.h only when no host heap tests --- components/heap/multi_heap_poisoning.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/components/heap/multi_heap_poisoning.c b/components/heap/multi_heap_poisoning.c index 559ad18d2e..3717b6c299 100644 --- a/components/heap/multi_heap_poisoning.c +++ b/components/heap/multi_heap_poisoning.c @@ -21,7 +21,10 @@ #include #include #include "multi_heap_internal.h" -#include "heap_private.h" +#if CONFIG_IDF_TARGET_ESP32S2BETA + #include "heap_private.h" +#endif + /* Note: Keep platform-specific parts in this header, this source file should depend on libc only */ From ce9f84fba9c519c93a773f514e2e43f8950c8d66 Mon Sep 17 00:00:00 2001 From: Felipe Neves Date: Tue, 19 Nov 2019 10:55:56 -0300 Subject: [PATCH 5/8] heap_caps: enable check of pointer on diram_iram for both S2 and non-S2 platform --- components/heap/heap_caps.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/components/heap/heap_caps.c b/components/heap/heap_caps.c index 28cb7bf4d1..316612cf6f 100644 --- a/components/heap/heap_caps.c +++ b/components/heap/heap_caps.c @@ -288,7 +288,6 @@ IRAM_ATTR void *heap_caps_realloc( void *ptr, size_t size, int caps) return NULL; } -#if CONFIG_IDF_TARGET_ESP32S2BETA //On esp32s2 the pointer to heap may be aliased, we need to //recover it before to manage a new allocation: if(esp_ptr_in_diram_iram((void *)ptr)) { @@ -297,7 +296,6 @@ IRAM_ATTR void *heap_caps_realloc( void *ptr, size_t size, int caps) ptr = (void *)dram_addr[-1]; //printf("[HEAP_CAPS_MALLOC]: obtained pointer that was aliased: %p \n", (void *)ptr); } -#endif heap_t *heap = find_containing_heap(ptr); assert(heap != NULL && "realloc() pointer is outside heap areas"); From 31145f38fa3e1649fe357efd03a50e8c4882b0b0 Mon Sep 17 00:00:00 2001 From: Felipe Neves Date: Tue, 19 Nov 2019 15:36:22 -0300 Subject: [PATCH 6/8] heap_caps: added special case for realloc when previous area is an diram_iram ptr, this will force a malloc/copy/free --- components/heap/heap_caps.c | 37 ++++++++++++++++++++------ components/heap/multi_heap_poisoning.c | 21 ++------------- 2 files changed, 31 insertions(+), 27 deletions(-) diff --git a/components/heap/heap_caps.c b/components/heap/heap_caps.c index 316612cf6f..2661bcb611 100644 --- a/components/heap/heap_caps.c +++ b/components/heap/heap_caps.c @@ -275,6 +275,10 @@ IRAM_ATTR void heap_caps_free( void *ptr) IRAM_ATTR void *heap_caps_realloc( void *ptr, size_t size, int caps) { + bool ptr_in_diram_case = false; + heap_t *heap = NULL; + void *dram_ptr = NULL; + if (ptr == NULL) { return heap_caps_malloc(size, caps); } @@ -288,23 +292,32 @@ IRAM_ATTR void *heap_caps_realloc( void *ptr, size_t size, int caps) return NULL; } - //On esp32s2 the pointer to heap may be aliased, we need to + //The pointer to memory may be aliased, we need to //recover it before to manage a new allocation: if(esp_ptr_in_diram_iram((void *)ptr)) { - //pointer must be already aliased, otherwise just ignore this part: uint32_t *dram_addr = (uint32_t *)ptr; - ptr = (void *)dram_addr[-1]; + dram_ptr = (void *)dram_addr[-1]; + //printf("[HEAP_CAPS_MALLOC]: obtained pointer that was aliased: %p \n", (void *)ptr); + + heap = find_containing_heap(dram_ptr); + assert(heap != NULL && "realloc() pointer is outside heap areas"); + + //with pointers that reside on diram space, we avoid to + //to use realloc implementation due to address translation issues, + //instead force a malloc/copy/free + ptr_in_diram_case = true; + + } else { + heap = find_containing_heap(ptr); + assert(heap != NULL && "realloc() pointer is outside heap areas"); } - heap_t *heap = find_containing_heap(ptr); - assert(heap != NULL && "realloc() pointer is outside heap areas"); - // are the existing heap's capabilities compatible with the // requested ones? bool compatible_caps = (caps & get_all_caps(heap)) == caps; - if (compatible_caps) { + if (compatible_caps && !ptr_in_diram_case) { // try to reallocate this memory within the same heap // (which will resize the block if it can) void *r = multi_heap_realloc(heap->heap, ptr, size); @@ -317,8 +330,16 @@ IRAM_ATTR void *heap_caps_realloc( void *ptr, size_t size, int caps) // in a different heap with requested capabilities. void *new_p = heap_caps_malloc(size, caps); if (new_p != NULL) { + size_t old_size = 0; + + //If we're dealing with aliased ptr, information regarding its containing + //heap can only be obtained with translated address. + if(ptr_in_diram_case) { + old_size = multi_heap_get_allocated_size(heap->heap, dram_ptr); + } else { + old_size = multi_heap_get_allocated_size(heap->heap, ptr); + } - size_t old_size = multi_heap_get_allocated_size(heap->heap, ptr); assert(old_size > 0); memcpy(new_p, ptr, MIN(size, old_size)); heap_caps_free(ptr); diff --git a/components/heap/multi_heap_poisoning.c b/components/heap/multi_heap_poisoning.c index 3717b6c299..ffe885150d 100644 --- a/components/heap/multi_heap_poisoning.c +++ b/components/heap/multi_heap_poisoning.c @@ -21,10 +21,6 @@ #include #include #include "multi_heap_internal.h" -#if CONFIG_IDF_TARGET_ESP32S2BETA - #include "heap_private.h" -#endif - /* Note: Keep platform-specific parts in this header, this source file should depend on libc only */ @@ -272,21 +268,8 @@ void *multi_heap_realloc(multi_heap_handle_t heap, void *p, size_t size) new_head = multi_heap_malloc_impl(heap, size + POISON_OVERHEAD); if (new_head != NULL) { result = poison_allocated_region(new_head, size); - -#if CONFIG_IDF_TARGET_ESP32S2BETA - //We may need to deal with aliased heap pointers. here too, - //mainly because the heap canary is located before the - //the slot reserved to preserve original DRAM address - //so the original user data is actually p + 4 ahead : - if(esp_ptr_in_diram_dram((void *)p)) { - memcpy(result, p + sizeof(intptr_t), MIN(size, orig_alloc_size)); - } else { - memcpy(result, p , MIN(size, orig_alloc_size)); - } -#else - memcpy(result, p, MIN(size, orig_alloc_size)); -#endif - multi_heap_free(heap, p); + memcpy(result, p, MIN(size, orig_alloc_size)); + multi_heap_free(heap, p); } #endif From 4909fdfe0220d74aefcdd385547ae0b21ab8bb69 Mon Sep 17 00:00:00 2001 From: Felipe Neves Date: Mon, 9 Dec 2019 12:05:19 -0300 Subject: [PATCH 7/8] heap_caps: small fixes on comments plus cleaning --- components/expat/expat | 2 +- components/heap/heap_caps.c | 8 +++----- components/lwip/lwip | 2 +- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/components/expat/expat b/components/expat/expat index a7bc26b697..968b8cc46d 160000 --- a/components/expat/expat +++ b/components/expat/expat @@ -1 +1 @@ -Subproject commit a7bc26b69768f7fb24f0c7976fae24b157b85b13 +Subproject commit 968b8cc46dbee47b83318d5f31a8e7907199614b diff --git a/components/heap/heap_caps.c b/components/heap/heap_caps.c index 2661bcb611..66d348ccd4 100644 --- a/components/heap/heap_caps.c +++ b/components/heap/heap_caps.c @@ -293,18 +293,16 @@ IRAM_ATTR void *heap_caps_realloc( void *ptr, size_t size, int caps) } //The pointer to memory may be aliased, we need to - //recover it before to manage a new allocation: + //recover the corresponding address before to manage a new allocation: if(esp_ptr_in_diram_iram((void *)ptr)) { uint32_t *dram_addr = (uint32_t *)ptr; dram_ptr = (void *)dram_addr[-1]; - //printf("[HEAP_CAPS_MALLOC]: obtained pointer that was aliased: %p \n", (void *)ptr); - heap = find_containing_heap(dram_ptr); assert(heap != NULL && "realloc() pointer is outside heap areas"); - //with pointers that reside on diram space, we avoid to - //to use realloc implementation due to address translation issues, + //with pointers that reside on diram space, we avoid using + //the realloc implementation due to address translation issues, //instead force a malloc/copy/free ptr_in_diram_case = true; diff --git a/components/lwip/lwip b/components/lwip/lwip index c9e3b53c6f..31e24ae95a 160000 --- a/components/lwip/lwip +++ b/components/lwip/lwip @@ -1 +1 @@ -Subproject commit c9e3b53c6f04052943f97210b858cec805cc98d9 +Subproject commit 31e24ae95a59e51d74f435f48fa21091b26c1430 From 8795b2681c73893b1fcc4ec4b2b93b30acb5a1ba Mon Sep 17 00:00:00 2001 From: Felipe Neves Date: Fri, 20 Dec 2019 13:48:09 -0300 Subject: [PATCH 8/8] heap: added test case for realloc to verify if successive realloc in IRAM still ends there. --- components/heap/test/test_realloc.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/components/heap/test/test_realloc.c b/components/heap/test/test_realloc.c index 763cddab62..ed2fe17b36 100644 --- a/components/heap/test/test_realloc.c +++ b/components/heap/test/test_realloc.c @@ -7,6 +7,7 @@ #include "unity.h" #include "sdkconfig.h" #include "esp_heap_caps.h" +#include "soc/soc_memory_layout.h" #ifndef CONFIG_HEAP_POISONING_COMPREHENSIVE @@ -22,6 +23,21 @@ TEST_CASE("realloc shrink buffer in place", "[heap]") #endif +TEST_CASE("realloc shrink buffer with EXEC CAPS", "[heap]") +{ + const size_t buffer_size = 64; + + void *x = heap_caps_malloc(buffer_size, MALLOC_CAP_EXEC); + TEST_ASSERT(x); + void *y = heap_caps_realloc(x, buffer_size - 16, MALLOC_CAP_EXEC); + TEST_ASSERT(y); + + //y needs to fall in a compatible memory area of IRAM: + TEST_ASSERT(esp_ptr_executable(y)); + + free(y); +} + TEST_CASE("realloc move data to a new heap type", "[heap]") { const char *test = "I am some test content to put in the heap";