Linker error - firmware.elf: hidden symbol `__dso_handle' isn't defined

Hey, when I try to compile my code, I’m getting a weird linker error, that I sadly don’t know how to fix.
It points to the instantiation of a local static variable that’s wrapped in a singleton.
The compilation target that throws this error is the STM32F407VG target(target/STM32F407VG ), where the implementation lives. The header files live in include/ and the InterruptVectorTable.hpp lives in include/hal/

The last commit introduced the error.

arm-none-eabi-g++ -o .pio/build/stm32f407vg/firmware.elf -T stm32f405x6.ld -Wl,--gc-sections,--relax -mthumb -nostartfiles -nostdlib -mcpu=cortex-m4 .pio/build/stm32f407vg/src/main.o .pio/build/stm32f407vg/src/target/STM32F407VG/InterruptVectorTable.o .pio/build/stm32f407vg/src/target/STM32F407VG/startup_stm32f4xx.o .pio/build/stm32f407vg/src/target/STM32F407VG/system_stm32f4xx.o -L/Users/john/.platformio/platforms/ststm32/ldscripts -L.pio/build/stm32f407vg -Wl,--start-group -lc -lgcc -lm -lstdc++ -lnosys -Wl,--end-group
.pio/build/stm32f407vg/src/main.o: In function `main':
/Users/john/Documents/PlatformIO/Projects/Testing_MCB1768/include/hal/InterruptVectorTable.hpp:133: undefined reference to `__dso_handle'
/Users/john/.platformio/packages/toolchain-gccarmnoneeabi/bin/../lib/gcc/arm-none-eabi/7.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m/libc.a(lib_a-fini.o): In function `__libc_fini_array':
fini.c:(.text.__libc_fini_array+0x26): undefined reference to `_fini'
/Users/john/.platformio/packages/toolchain-gccarmnoneeabi/bin/../lib/gcc/arm-none-eabi/7.2.1/../../../../arm-none-eabi/bin/ld: .pio/build/stm32f407vg/firmware.elf: hidden symbol `__dso_handle' isn't defined
/Users/john/.platformio/packages/toolchain-gccarmnoneeabi/bin/../lib/gcc/arm-none-eabi/7.2.1/../../../../arm-none-eabi/bin/ld: final link failed: Bad value
collect2: error: ld returned 1 exit status
*** [.pio/build/stm32f407vg/firmware.elf] Error 1

here’s my repo/branch: GitHub - jxsl13/lpc1768_blinky_example at non_stl_abstraction

If I’m not mistaken, it is related to a combination of complex C++ object destruction of static objects and the nostdlib compiler option.

In an embedded system, you likely don’t need the destruction of static objects. So try this compiler option: -fno-use-cxa-atexit.

Interesting read:

1 Like

Adding that build flag throws a new error, which looks less intimidating than the previous one, but still intimidating.

The terminal process terminated with exit code: 1

Terminal will be reused by tasks, press any key to close it.

> Executing task: platformio run --environment stm32f407vg <

Processing stm32f407vg (platform: ststm32; board: disco_f407vg)
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
CONFIGURATION: https://docs.platformio.org/page/boards/ststm32/disco_f407vg.html
PLATFORM: ST STM32 5.7.0 > ST STM32F4DISCOVERY
HARDWARE: STM32F407VGT6 168MHz, 128KB RAM, 1MB Flash
DEBUG: Current (stlink) On-board (stlink) External (blackmagic, jlink)
PACKAGES: toolchain-gccarmnoneeabi 1.70201.0 (7.2.1)
LDF: Library Dependency Finder -> http://bit.ly/configure-pio-ldf
LDF Modes: Finder ~ chain, Compatibility ~ soft
Found 0 compatible libraries
Scanning dependencies...
No dependencies
arm-none-eabi-g++ -o .pio/build/stm32f407vg/src/main.o -c -fno-rtti -fno-exceptions -std=c++1z -std=gnu++1z -ffunction-sections -fdata-sections -Wall -mthumb -nostdlib -mcpu=cortex-m4 -fno-use-cxa-atexit -Og -g3 -ggdb3 -DF_CPU=168000000L -DDISCO_F407VG -DPLATFORMIO=40003 -DSTM32F4 -DSTM32F407xx -DSTM32F40_41xxx -DARDUINO_STM32DiscoveryF407 -DBOARD_discovery_f4 -DSTM32F407VG -DDEBUG -D__PLATFORMIO_BUILD_DEBUG__ -Iinclude -Isrc src/main.cpp
arm-none-eabi-g++ -o .pio/build/stm32f407vg/src/target/STM32F407VG/InterruptVectorTable.o -c -fno-rtti -fno-exceptions -std=c++1z -std=gnu++1z -ffunction-sections -fdata-sections -Wall -mthumb -nostdlib -mcpu=cortex-m4 -fno-use-cxa-atexit -Og -g3 -ggdb3 -DF_CPU=168000000L -DDISCO_F407VG -DPLATFORMIO=40003 -DSTM32F4 -DSTM32F407xx -DSTM32F40_41xxx -DARDUINO_STM32DiscoveryF407 -DBOARD_discovery_f4 -DSTM32F407VG -DDEBUG -D__PLATFORMIO_BUILD_DEBUG__ -Iinclude -Isrc src/target/STM32F407VG/InterruptVectorTable.cpp
arm-none-eabi-gcc -x assembler-with-cpp -ffunction-sections -fdata-sections -Wall -mthumb -nostdlib -mcpu=cortex-m4 -DF_CPU=168000000L -DDISCO_F407VG -DPLATFORMIO=40003 -DSTM32F4 -DSTM32F407xx -DSTM32F40_41xxx -DARDUINO_STM32DiscoveryF407 -DBOARD_discovery_f4 -DSTM32F407VG -DDEBUG -D__PLATFORMIO_BUILD_DEBUG__ -Iinclude -Isrc -c -o .pio/build/stm32f407vg/src/target/STM32F407VG/startup_stm32f4xx.o src/target/STM32F407VG/startup_stm32f4xx.S
arm-none-eabi-gcc -o .pio/build/stm32f407vg/src/target/STM32F407VG/system_stm32f4xx.o -c -ffunction-sections -fdata-sections -Wall -mthumb -nostdlib -mcpu=cortex-m4 -fno-use-cxa-atexit -Og -g3 -ggdb3 -DF_CPU=168000000L -DDISCO_F407VG -DPLATFORMIO=40003 -DSTM32F4 -DSTM32F407xx -DSTM32F40_41xxx -DARDUINO_STM32DiscoveryF407 -DBOARD_discovery_f4 -DSTM32F407VG -DDEBUG -D__PLATFORMIO_BUILD_DEBUG__ -Iinclude -Isrc src/target/STM32F407VG/system_stm32f4xx.c
In file included from include/hal/InterruptVectorTable.hpp:3:0,
                 from src/main.cpp:3:
include/config.hpp:6:35: note: #pragma message: 201703L
 #pragma message (XSTR(__cplusplus))
                                   ^
cc1: warning: command line option '-fno-use-cxa-atexit' is valid for C++/ObjC++ but not for C
In file included from include/hal/InterruptVectorTable.hpp:3:0,
                 from src/target/STM32F407VG/InterruptVectorTable.cpp:2:
include/config.hpp:6:35: note: #pragma message: 201703L
 #pragma message (XSTR(__cplusplus))
                                   ^
arm-none-eabi-g++ -o .pio/build/stm32f407vg/firmware.elf -T stm32f405x6.ld -Wl,--gc-sections,--relax -mthumb -nostartfiles -nostdlib -mcpu=cortex-m4 .pio/build/stm32f407vg/src/main.o .pio/build/stm32f407vg/src/target/STM32F407VG/InterruptVectorTable.o .pio/build/stm32f407vg/src/target/STM32F407VG/startup_stm32f4xx.o .pio/build/stm32f407vg/src/target/STM32F407VG/system_stm32f4xx.o -L/Users/john/.platformio/platforms/ststm32/ldscripts -L.pio/build/stm32f407vg -Wl,--start-group -lc -lgcc -lm -lstdc++ -lnosys -Wl,--end-group
/Users/john/.platformio/packages/toolchain-gccarmnoneeabi/bin/../lib/gcc/arm-none-eabi/7.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m/libc.a(lib_a-fini.o): In function `__libc_fini_array':
fini.c:(.text.__libc_fini_array+0x26): undefined reference to `_fini'
collect2: error: ld returned 1 exit status
*** [.pio/build/stm32f407vg/firmware.elf] Error 1

It’s not so bad. One of the undefined references is gone (success) but a new warning appeared. It’s just a warning that says -fno-use-cxa-atexit is okay for the C++ compiler but not for the C compiler. Unfortunately, I don’t know how to specify compiler options to the C compiler only.

The second undefined reference is still present, however:

fini.c:(.text.__libc_fini_array+0x26): undefined reference to `_fini'

Again, it’s related to cleanup when a program finishes, i.e. something not needed on an embedded device. Unfortunately, I have no idea which part of your code wants to use it. You might need to inspect all object files to find the one adding something to the .fini_array ELF section…

2 Likes

I found the solution, it’s not really related to those flags, but maybe a little bit. At least your help lead me to find the error. I was using empty destructors everywhere in case I would need them for some implementation. I guess I will not need them, as I guess static objects are not supposed to be ever destroyed in an embedded context.

Thus I removed the destructors and their “implementation” and it works fine now.
Thanks for being a great help like always in this forum!

1 Like

hey i don’t have any destructor and static functions still i am getting this error

Please post the content of your platform.ini file, the full log output and if possible your source code.

2 Likes