Description
Description of defect
When using the function memalign() or aligned_alloc() to get aligned memory, then it crashes when the heap statistics is turned on. This even does not happen in every case, it depends also on the address that malloc returns to memalign. memalign requests more memory than necessary for the finding an aligned block, and may return a portion of the oversized allocation.
Aligned memory with granularity e.g. 32 Bytes is important for correct alignment for DMA and D-cache maintainance. These functions are available in gcc, but unfornately not in ARMCC. aligned_alloc is in already in C11, memalign() was existent in gcc / newlib for longer time already. From gcc 10.3.0, aligned_alloc() calls _memalign_r(), before it called posix_memalign which caused a linker unresolved symbol error.
The problem is the way that malloc and heap statistics in platform/source/mbed_alloc_wrappers.cpp are working:
- there are wrappers for the malloc/free functions that manipulate the pointer from __real_malloc
- the newlib also manipulates the malloc pointer with some internal knowledge of the structure before the pointer
The heap statistics in malloc add a alloc_info_t structure and this is causing the problem. By removing this, the heap statistics still work and no hardfault is triggered. The alloc_info is added for checking if free or realloc have to use a memory block from the wrapper or __real_alloc. Usually, all alloc calls should be redirected to the wrapper function, I don't know which cases are caught here.
Solutions would be
- permit use of memalign with heap statistics (bad option)
- fix the problem with manipulation by memalign (difficult, memalign uses functions to create heap blocks)
- remove the alloc_info
A similiar report may have been this issue: #13181
Target(s) affected by this defect ?
Many, tested with DISCO_F769NI and DISCO_F746NG
Toolchain(s) (name and version) displaying this defect ?
gcc 8.3.0 up to gcc 12.2.2
ARMCC unfortunately does not support memalign
What version of Mbed-os are you using (tag or sha) ?
mbed-os-6.16.0
What version(s) of tools are you using. List all that apply (E.g. mbed-cli)
mbed-cli
How is this defect reproduced ?
#include "mbed.h"
#include <malloc.h>
DigitalOut led(LED1);
volatile char dummy[2048]; // change size in increments by 4 if problem is not visible
int main()
{
dummy[0] = 42; // avoid removing by optimization
size_t size = 512; // size of allocated blocks, does not matter
void *p1 = malloc(size); // always ok when mem is available
printf("pointer p1: %p\n", p1);
fflush(stdout);
void *p2 = malloc(size); // always ok when mem is available
printf("pointer p2: %p\n", p2);
fflush(stdout);
void *p3 = memalign(32, size); // aligned_alloc(32, size); // craches in many cases
printf("pointer p3: %p\n", p3);
fflush(stdout);
while(true) {
led = !led;
ThisThread::sleep_for(1s);
}
return 0;
}
in mbed_app.json, it is neccessary to turn on the heap statistics:
{
"target_overrides": {
"*": {
"target.printf_lib": "std",
"platform.stdio-baud-rate": 115200,
"platform.stdio-buffered-serial": 1,
"platform.all-stats-enabled": 1
}
}
}