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

NUMAKER_PFM_NUC472 LWIP tests fail with heap statistics enabled #3440

Closed bridadan closed 6 years ago

bridadan commented 7 years ago

Description


Bug

Target NUMAKER_PFM_NUC472

Toolchain: GCC_ARM

mbed-cli version: 1.0.0

meed-os sha: aa6780d Merge pull request #3416 from bridadan/rename_stm32f1_i2c_api

DAPLink version: N/A (Using default Nuvoton firmware)

Expected behavior All LWIP tests should pass, even when run-time memory statistics are enabled.

Actual behavior LWIP tests fail when heap statistics are enabled.

Steps to reproduce Run the following commands in order (the first command just builds, the second command just runs the tests)

mbed test -m NUMAKER_PFM_NUC472 -t GCC_ARM -n features-feature_lwip* --compile -DMBED_HEAP_STATS_ENABLED=1
mbed test -m NUMAKER_PFM_NUC472 -t GCC_ARM -n features-feature_lwip* --run -v
bridadan commented 7 years ago

cc @ccli8

bridadan commented 7 years ago

Any news @ccli8?

ccli8 commented 7 years ago

It is related to NUC472's LWIP Ethernet porting. We are checking. @cyliangtw

ccli8 commented 7 years ago

I intercept the calls to wrapped functions below:

__wrap__malloc_r
__wrap__realloc_r
__wrap__free_r
__wrap__calloc_r

And find a strange point with call stack below:

__wrap__malloc_r > __real__malloc_r > __wrap__free_r

In some unknown condition, __real__realloc_r will invocate _free_r, but it is __wrap__free_r rather than __real__free_r that gets called here.

  1. __wrap__free_r is called in __real_malloc_r but I cannot find paired __wrap__malloc_r in front.
  2. To my understanding, even though the four functions above are wrapped, because the four functions' implementations of __real_ version are placed in the same .c file in newlib (if I am not wrong about it), their calls to each other should be __real_ version rather than __wrap_ version. @bridadan can you clarify this point regarding ARM_GCC toolchain?
bridadan commented 7 years ago

@ccli8 I'm not all that familiar with this process either. Any ideas @c1728p9 @0xc0170 ?

0xc0170 commented 7 years ago

@ccli8

If a symbol is undefined, it is replaced by __wrap. If __real is undefined, it's replaced by symbol.

  1. wrapfree_r is called in real_malloc_r but I cannot find paired wrap__malloc_r in front.

paired wrapmalloc_r in front ? Can you provide a bit more details?

ccli8 commented 7 years ago

@0xc0170 In mbed-os/nu-porting/mbed-os/platform/mbed_alloc_wrappers.cpp, __wrap__malloc_r calls __real__malloc_r. With call stack, I also find __real__malloc_r internally calls __wrap__free_r. So I got the call sequence:

wrapmalloc_r > realmalloc_r > wrapfree_r

I intercept all calls to __wrap, so there should have been one call to __wrap__malloc_r before which could pair the call to __wrap__free_r here by comparing allocated memory address. But I cannot find such one. In my opinion, it would be correct if __real__free_r rather than __wrap__free_r were called by __real__malloc_r internally. This conjecture needs GCC toolchain (and newlib) details for verification.

ghost commented 6 years ago

GitHib issue review: Closed due to inactivity. Please re-file if critical issues found.

ccli8 commented 5 years ago

8062 would fix the issue by adding signature to check if a memory block is allocated by __wrap__malloc_r before free. If yes, __wrap__free_r would go normal path; otherwise, __wrap__free_r would degrade to __real__free_r.