2 years, 7 months ago.

MBED CLI __wrap_exit

Hi I am attempting to install CLI and ARM GCC. I *think* everything installed OK. However, when I attempt to follow the "Learn to use Mbed CLI:Quickstart" video on youtube, the compile exits with a whole bunch of errors related to "wrap_exit" . Here is a snip from the command line

c:/tools/gnu tools arm embedded/7 2017-q4-major/bin/../lib/gcc/arm-none-eabi/7.2 .1/../../../../arm-none-eabi/lib/thumb/v7-m/crt0.o: In function `_start': (.text+0x4e): undefined reference to `wrap_exit' ./mbed/f9eeca106725/TARGET_NUCLEO_F103RB/TOOLCHAIN_GCC_ARM\libmbed.a(error.o): I n function `error': error.c:(.text.error+0x16): undefined reference to `wrap_exit' collect2.exe: error: ld returned 1 exit status

Any hints on what's causing this and how to fix? Thanks Bill

1 Answer

2 years, 7 months ago.

Hello Bill,

I came across with two issues when using Qt Creator to build MBED projects offline with GNU ARM embedded toolchain. Maybe it can help you to fix the problem you experience when using mbed CLI:

  1. Precompiler directives (like #if ...) in linker files are not supported by the GNU ARM embedded toolchain:
    https://os.mbed.com/questions/79943/Linking-error-with-CoIDE/

  2. The platform\mbed_retarget.cpp file did not compile. To fix it I commented out the definition of the extern "C" void _exit(int return_code) function as below:

mbed_retarget.cpp

...

//#if defined(TOOLCHAIN_GCC_ARM) || defined(TOOLCHAIN_GCC_CR)
//extern "C" void _exit(int return_code) {
//#else
//namespace std {
//extern "C" void exit(int return_code) {
//#endif

//#if DEVICE_STDIO_MESSAGES
//#if MBED_CONF_PLATFORM_STDIO_FLUSH_AT_EXIT
//    fflush(stdout);
//    fflush(stderr);
//#endif
//#endif

//#if DEVICE_SEMIHOST
//    if (mbed_interface_connected()) {
//        semihost_exit();
//    }
//#endif
//    if (return_code) {
//        mbed_die();
//    }

//    while (1);
//}

//#if !defined(TOOLCHAIN_GCC_ARM) && !defined(TOOLCHAIN_GCC_CR)
//} //namespace std
//#endif

...

and modified the void __wrap_exit(int return_code) function as below:

mbed_retarget.cpp

...

#if defined(TOOLCHAIN_GCC)

/*
 * Depending on how newlib is  configured, it is often not enough to define
 * __aeabi_atexit, __cxa_atexit and __cxa_finalize in order to override the
 * behavior regarding the registration of handlers with atexit.
 *
 * To overcome this limitation, exit and atexit are overriden here.
 */
extern "C"{

/**
 * @brief Retarget of exit for GCC.
 * @details Unlike the standard version, this function doesn't call any function
 * registered with atexit before calling _exit.
 */
void __wrap_exit(int return_code) {
//    exit(return_code);
#if DEVICE_STDIO_MESSAGES
#if MBED_CONF_PLATFORM_STDIO_FLUSH_AT_EXIT
    fflush(stdout);
    fflush(stderr);
#endif
#endif

#if DEVICE_SEMIHOST
    if (mbed_interface_connected()) {
        semihost_exit();
    }
#endif
    if (return_code) {
        mbed_die();
    }

    while (1);
}

/**
 * @brief Retarget atexit from GCC.
 * @details This function will always fail and never register any handler to be
 * called at exit.
 */
int __wrap_atexit(void (*func)()) {
    return 1;
}

}

#endif

...

With best regards,

Zoltan

Thank You very much Zoltan!

I did what You say to do and now simple 'mbed_blinky' compile on my laptop.

In the beginning I had error

windows 7 o.s. command line interface mbed compile command failing with error

 ... arm-none-eabi/lib/thumb/v7e-m+fp/softfp/crt0.o: in function `_start': 
(.text+0x4e): undefined reference to `__wrap_exit'

I read Your infos/advices and I checked whether or not linked libmbed.a had definition of `_ _ wrap_exit', since it was not the case, then I just added to main.cpp what You have in the second mbed_retarget.cpp code box defining `_ _ wrap_exit' and `_ _ wrap_atexit' and now it compiles right as You can see below.

Thank Your a lot!

windows 7 o.s. command line interface fixing steps

C:\Users\user\workspace\mbed_blinky>arm-none-eabi-nm mbed\f9eeca106725\TARGET_NUCLEO_L476RG\TOOLCHAIN_GCC_ARM\libmbed.a > tmp.txt

C:\Users\user\workspace\mbed_blinky>del ".main.cpp.un~"

C:\Users\user\workspace\mbed_blinky>mbed compile
[mbed] Working path "C:\Users\user\workspace\mbed_blinky" (program)
WARNING: MBED_ARM_PATH set as environment variable but doesn't exist
WARNING: MBED_GCC_ARM_PATH set as environment variable but doesn't exist
Using targets from C:\Users\user\workspace\mbed_blinky\mbed\f9eeca106725\targets.json
[Error] @,: Compiler version mismatch: Have 8.3.1; expected version >= 6.0.0 and < 7.0.0
Building project mbed_blinky (NUCLEO_L476RG, GCC_ARM)
Scan: mbed_blinky
Compile [100.0%]: main.cpp
Link: mbed_blinky
Elf2Bin: mbed_blinky
| Module              |         .text |     .data |      .bss |
|---------------------|---------------|-----------|-----------|
| BUILD\NUCLEO_L476RG |     235(+235) |     4(+4) |   20(+20) |
| [fill]              |       39(+39) |     0(+0) |     9(+9) |
| [lib]\c_nano.a      |   2491(+2491) | 100(+100) |   12(+12) |
| [lib]\gcc.a         |     772(+772) |     0(+0) |     0(+0) |
| [lib]\mbed.a        |   3246(+3246) |     4(+4) | 230(+230) |
| [lib]\misc          |     208(+208) |   12(+12) |   28(+28) |
| [lib]\stdc++_nano.a |       10(+10) |     0(+0) |     0(+0) |
| mbed\f9eeca106725   |   6559(+6559) |   12(+12) |   69(+69) |
| Subtotals           | 13560(+13560) | 132(+132) | 368(+368) |
Total Static RAM memory (data + bss): 500(+500) bytes
Total Flash memory (text + data): 13692(+13692) bytes

Image: .\BUILD\NUCLEO_L476RG\GCC_ARM\mbed_blinky.bin

C:\Users\user\workspace\mbed_blinky>

By the way, - before the compiling stuff - I installed json-schema https://json-schema.org/ and py-elftools https://github.com/eliben/pyelftools with

windows 7 o.s. command line interface pip install latest version of specified packages

pip install --upgrade jsonschema
pip install --upgrade pyelftools

Bye! Giangiacomo

P.S. with GNU/Linux o.s. it is exactly the same

posted by Giangiacomo Zaffini 05 Aug 2019