esp-idf: [TW#12147] Unable to switch on C++ exception handling -fexceptions (IDFGH-2244)

I am working in C++ and wish to switch on exception handling. I compiled my C++ code by enabling the GCC flag called -fexceptions. I did this by editing my local component.mk and adding:

CXXFLAGS+=-fexceptions

The code seems to compile cleanly however when I run “make” for the ESP-IDF build system, we abort at the end with the following:

$ make
CXX BLEUtils.o
/home/kolban/esp32/esptest/apps/workspace/bt_test/components/cpp_utils/./BLEUtils.cpp:181:20: 
AR libcpp_utils.a
LD app-template.elf
esptool.py v2.0-beta2
Traceback (most recent call last):
  File "/home/kolban/esp32/esptest/esp-idf/components/esptool_py/esptool/esptool.py", line 2294, in <module>
    main()
  File "/home/kolban/esp32/esptest/esp-idf/components/esptool_py/esptool/esptool.py", line 2096, in main
    operation_func(args)
  File "/home/kolban/esp32/esptest/esp-idf/components/esptool_py/esptool/esptool.py", line 1732, in elf2image
    image.save(args.output)
  File "/home/kolban/esp32/esptest/esp-idf/components/esptool_py/esptool/esptool.py", line 1306, in save
    assert (f.tell() + 8) % IROM_ALIGN == segment.addr % IROM_ALIGN
AssertionError
/home/kolban/esp32/esptest/esp-idf/components/esptool_py/Makefile.projbuild:49: recipe for target '/home/kolban/esp32/esptest/apps/workspace/bt_test/build/app-template.bin' failed
make: *** [/home/kolban/esp32/esptest/apps/workspace/bt_test/build/app-template.bin] Error 1

Unfortunately, I don’t know how to make progress from here.

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Comments: 21 (18 by maintainers)

Commits related to this issue

Most upvoted comments

@igrr: Ok, when I am done with work, I’ll send a PR modifying startup function and linker script. I’ll leave the rest up to you - thanks! Can I have also a request to add the possibility to enable RTTI?

@hwmaier I vote for having exceptions enabled by default (of course with the possibility to disable them). ESP32 is no a small platform anymore, the implementation of exception is zero-cost and most of the beginners with ESP32 are not going to reach flash limits and with exceptions enable by default they can easily use all features of C++. If a user wants to save memory, he is not a beginner anymore and he should be able to disable exceptions and RTTI.

@projectgus is correct, there is more to exception support than adding exception tables sections to the linker script. We also need to have a separate build of libstdc++, as the current one is built with exceptions disabled. A customer has recently requested this feature, I will be working on it.

That’s great progress, @yaqwsx. My suggestion is to introduce a (disabled by default) Kconfig option for “C++ exception handling”. With this option enabled, we link against the (newly added) libgcc-fexceptions.a. Otherwise, we use the existing libgcc.a and add -fno-exceptions to CXXFLAGS. Feel free to make a PR with part of the changes (linker script change and the call to __register_frame_info) if you don’t feel comfortable modifying makefiles. I can make the makefile change and add the new libgcc version on top of your PR. I think that hardcoding size for __register_frame_info is okay.

With regards to GCC 6.3, we’ll test our code against it, and if all goes well, we will upgrade for the next major version of SDK.

Thanks @nkolban . xtensa-esp32-elf-objdump -h app-template.elf shows that the gcc exception structures are being linked in to the default “flash” address space as separate sections:

  7 .gcc_except_table._Z41__static_initialization_and_destruction_0ii 000001b5  4015db5d  4015db5d  000cc93d  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  8 .gcc_except_table._ZL12uuidToString13esp_bt_uuid_t 0000002c  4015dd12  4015dd12  000ccaf2  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  9 .gcc_except_table._ZL14gattIdToString13esp_gatt_id_t 00000031  4015dd3e  4015dd3e  000ccb1e  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
 10 .gcc_except_table._ZL35characteristic_properties_to_string20esp_gatt_char_prop_t 0000002b  4015dd6f  4015dd6f  000ccb4f  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
 11 .gcc_except_table._ZN8BLEUtils15addressToStringENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE 0000002b  4015dd9a  4015dd9a  000ccb7a  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
 12 .gcc_except_table._ZN8BLEUtils17registerByAddressENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEP9BLEDevice 00000020  4015ddc5  4015ddc5  000ccba5  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
 13 .gcc_except_table._Z23bt_utils_log_gatt_event20esp_gattc_cb_event_thP24esp_ble_gattc_cb_param_t 000000a2  4015dde5  4015dde5  000ccbc5  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
etc, etc.

and this long list of additional flash-resident sections is what is causing the (fairly cryptic) IROM-related assertion in esptool.py.

The workaround may be as simple as adding .gcc_except_table.* to the list of IRAM sections in esp32.common.ld (not sure if it’s safe to put them in flash, in case an exception occurs while flash cache is disabled.) Or perhaps there is some way to split the linkage of exception tables between those exception tables that belong to IRAM functions and those which do not.

I’m going to rope in @igrr here as I think this may be the tip of a larger iceberg of support that’s required for C++ exceptions to work properly. Ivan have you already looked into this at all?