Malloc hang when using platform.heap-stats-enabled=true in combination with -O2/-O3


We encountered a complex issue recently when running our application in release mode (where it is built with -O2). I don’t want to presume that this is a bug within mbed-os, so I am posting this to the general section.

What we want to achieve:
We simply try to printf a float from some thread.

Extra info:

  1. We use a custom printf implementation which overrides the stdlib printf. We decided on this because the other printf implementations seem to either be huge in terms of code size or don’t support things such as padding. After analysis it does not seem like this introduces any problems, since we can clearly trace what parameters are passed and where the program hangs
  2. We have platform.heap-stats-enabled=true in mbed_app.json
  3. We use mbed-os 6.3 and ARM_GCC 9.3.1

The problem we encounter:
In debug mode, we use -Og and we do not experience any problems.
In release mode, we use -O2 and we experience our application seemingly hanging during the call to vsnprintf, which is the stdlib function that our custom printf implementation calls.

The following is a call trace obtained while debugging:
printf (custom)
vfprintf (custom)
vsnprintf (stdlib)
__wrap_calloc_r (mbed-os wrapper due to platform.heap-stats-enabled=true)

This last function makes a call to malloc:
ptr = malloc(nmemb * size);

And that’s seemingly where the program freezes until our SW watchdog triggers.
When I step into this, the final entry of the debug call trace keeps switching between:
__wrap__calloc_r() at mbed_alloc_wrappers.cpp:244 0x8016d5c
calloc() at 0x8027150

If I disable platform.heap-stats-enabled, then the problem disappears completely. I’m not sure how to proceed at this point and I was wondering if other developers experienced similar behavior.