ARMmbed / mbed-os

Arm Mbed OS is a platform operating system designed for the internet of things
https://mbed.com
Other
4.66k stars 2.97k forks source link

Heap stats do not change after malloc() on NRF52_DK #14234

Open OllyMcBrideOB opened 3 years ago

OllyMcBrideOB commented 3 years ago

Description of defect

When running the example code & configuration from Heap Statistics tutorial, the heap stats do not change after a successful malloc(). My initial thoughts are that the malloc_wrapper() is not being called, and therefore the heap stats are not being tallied. However the MBED_HEAP_STATS_ENABLED configuration appears to be set correctly, so I'm unsure as to why this issue is occurring.

Target(s) affected by this defect ?

NRF52_DK

Toolchain(s) (name and version) displaying this defect ?

n/a

What version of Mbed-os are you using (tag or sha) ?

d9819a72d1d2daea0609e921efde49e9ba06c9b7

What version(s) of tools are you using. List all that apply (E.g. mbed-cli)

n/a

How is this defect reproduced ?

Using the instructions on the Heap Statistics tutorial, I have copied and pasted main() and the mbed_app.json configuration into mbed-os-example-blinky and tried to run it on a Nordic NRF52832 Dev Kit (PCA10400).

The output of the serial monitor is shown below:

Starting heap stats example
Start; Current heap: 64
Start; Max heap size: 64

Allocating 1000 bytes
Post-Alloc; Current heap: 64
Post-Alloc; Max heap size: 64

Freed 1000 bytes
Post-Free; Current heap: 64
Post-Free; Max heap size: 64

However, there is no change in the 'Post-Alloc' heap size. I would expect to see the following to indicate that the MBED_HEAP_STATS_ENABLED is enabled and the malloc() was successful:

Starting heap stats example
Start; Current heap: 64
Start; Max heap size: 64

Allocating 1000 bytes
Post-Alloc; Current heap: 1064
Post-Alloc; Max heap size: 1064

Freed 1000 bytes
Post-Free; Current heap: 64
Post-Free; Max heap size: 1064

Or I would expect to see the following, which should indicate that MBED_HEAP_STATS_ENABLED is not enabled:

Starting heap stats example
Start; Current heap: 0
Start; Max heap size: 0

Allocating 1000 bytes
Post-Alloc; Current heap: 0
Post-Alloc; Max heap size: 0

Freed 1000 bytes
Post-Free; Current heap: 0
Post-Free; Max heap size: 0

My initial thought was that the MBED_HEAP_STATS_ENABLED configuration was not being set properly, resulting in the stdlib malloc() being called instead of the mbed malloc_wrapper(), which includes the heap stats tracing.

The output from mbed compile --config -tARM -mNRF52_DK seems to indicate that the configuration setting is set correctly (see image).

image

I'm currently out of ideas as to why the heap stats doesn't function as expected,

For reference, the image below shows a screenshot of the program, configuration and unexpected output.

image

ciarmcom commented 3 years ago

@OllyMcBrideOB thank you for raising this issue.Please take a look at the following comments:

Could you add some more detail to the description? A good description should be at least 25 words.

NOTE: If there are fields which are not applicable then please just add 'n/a' or 'None'. This indicates to us that at least all the fields have been considered. Please update the issue header with the missing information, the issue will not be mirrored to our internal defect tracking system or investigated until this has been fully resolved.

ciarmcom commented 3 years ago

Thank you for raising this detailed GitHub issue. I am now notifying our internal issue triagers. Internal Jira reference: https://jira.arm.com/browse/IOTOSM-3388

pan- commented 3 years ago

That's a great description. Thanks @OllyMcBrideOB . Have you tried with a different compiler like GCC ?

I tried with GCC on an NRF52840 and I obtain the following result:

Starting heap stats example
Start; Current heap: 1034
Start; Max heap size: 1034

Allocating 1000 bytes
allocation = 0x20002fd0
Post-Alloc; Current heap: 2034
Post-Alloc; Max heap size: 2034

Freed 1000 bytes
Post-Free; Current heap: 1034
Post-Free; Max heap size: 2034

@evedon It seems that the doc promote the wrong method to enable the heap statistics, it should be

    "target_overrides": {
        "*": {
            "platform.heap-stats-enabled": true
        }
    }

and not

{
    "macros": [
        "MBED_HEAP_STATS_ENABLED=1"
    ],
    ...
}
evedon commented 3 years ago

@pan- You are right that we should update the tutorial to promote using platform.heap-stats-enabled and not the macro name. The documentation page on the configuration system correctly discourages the usage of the macro.

OllyMcBrideOB commented 3 years ago

Hi @pan-,

I have changed my mbed_app.json file to use:

{
"target_overrides": {
        "*": {
            "platform.heap-stats-enabled": true
        }
    }
}

And have compiled for NRF52_DK using GCC_ARM (running on a NRF52832 PCA10400 dev kit) and I get the following:

Starting heap stats example
Start; Current heap: 1024
Start; Max heap size: 1024

Allocating 1000 bytes
Post-Alloc; Current heap: 1024
Post-Alloc; Max heap size: 1024

Freed 1000 bytes
Post-Free; Current heap: 1024
Post-Free; Max heap size: 1024

When I run mbed compile -m NRF52_DK -t GCC_ARM --config I have confirmed that the heap-stats-enabled configuration is set correctly:

platform.heap-stats-enabled = 1 (macro name: "MBED_HEAP_STATS_ENABLED")

My current thinking is that one of the following 2 options is occurring:

  1. malloc_wrapper() is being called correctly, however mbed_alloc_wrappers.cpp isn't seeing the configuration options and therefore the heap stats tracking functionality is disabled.
  2. The stdlib malloc() is being called instead of malloc_wrapper(), meaning that there is no way to track the heap stats.

Do you have any thoughts on whether any of the above options are possible and how to prove/disprove them? Or whether there are other possible causes?

For reference, the image below shows a screenshot of the program now compiled using GCC_ARM, the changed mbed_app.json configuration and unexpected output.

image

0xc0170 commented 3 years ago

enable also MBED_MEM_TRACING_ENABLED, see https://os.mbed.com/blog/entry/Tracking-memory-usage-with-Mbed-OS/ for details.

OllyMcBrideOB commented 3 years ago

I've just revisited this issue and have managed to get the Heap Stats working on the NRF52832 using the GCC_ARM compiler.

Using Mbed Studio, it turns out I didn't properly configure it to use GCC_ARM, and therefore it was still using ARM6. As soon as I (correctly) followed the instructions here and configured Mbed Studio for GCC_ARM, the Heap Stats functionality is working successfully.

As far as I understand it, the malloc() wrapper functionality is enabled by using the --wrap flag for the GCC_ARM compiler mbed-os/tools/profiles/debug.json. Is it possible to either enable the malloc() wrapper functionality for the ARM6 compiler, to prevent others from experiencing the same issue? Or are we able to to add a note to the Heap Statistics tutorial to specify that it will only work with GCC_ARM?