platformio / platform-ststm32

ST STM32: development platform for PlatformIO
https://registry.platformio.org/platforms/platformio/ststm32
Apache License 2.0
394 stars 307 forks source link

C++ exceptions don't work with default GCC9 but work with older GCC7 #619

Open positron96 opened 2 years ago

positron96 commented 2 years ago

If you enable exceptions, they only work when compiled with older GCC (tested with GCC 6 and GCC 7). When compiled with default toolchain for arduino framework (GCC 9), exception support is not compiled in and the exceptions lead to hanging.

Reproducible example:

The example is for Nucleo-F401 board that I have, but the issue also manifests with STMF407 and probably with other MCUs.

[env:board]
build_unflags = -fno-exceptions --specs=nano.specs
build_flags = -fexceptions
platform = ststm32
board = genericSTM32F401RE
framework = arduino
platform_packages = toolchain-gccarmnoneeabi@~1.70201.0 

upload_protocol = jlink
debug_tool = jlink
#include <Arduino.h>

void setup() {
  Serial.begin(115200);

  Serial.println("start");
  try {
    throw 1;
  } catch(...) {
    Serial.println("EXCEPTION");
  }
}

void loop() {
  Serial.println("tick");
  delay(1000);
}

This is a simple project for Arduino framework with exceptions enabled. Config is inspired by this issue. If you build it and upload the 76k binary (change upload_protocol if needed), you get what is expected on Serial:

start
EXCEPTION
tick
tick
...

However, if you comment platform_packages = line and use default GCC (which for Arduino framework is toolchain-gccarmnoneeabi 1.90201.191206 (9.2.1)), the binary gets slimmer at 24k and excpetions are never caught: the program only shows start before hanging forever in _exit.

I've tested these versions of GCC package:

Affected: 1.90201.191206 (9.2.1) Not affected: 1.70201.0 (7.2.1), 1.60301.0 (6.3.1)

jcw commented 2 years ago

I can confirm this on stm32f407 (disco_f407vg) - had to add monitor_speed = 115200 to see the output. It also works with toolchain-gccarmnoneeabi@1.80201.181220. FWIW, it only works with --specs=nano.specs mentioned in build_ungflags.

(I only tried this out of curiosity, the 50+ kB code overhead - just to enable exceptions - is excessive for me)