This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

libsupc++_nano.a and C++ exceptions

Hi,

We'd like to add support for C++ exceptions (yes...) to our embedded firmware.  Up until now we've been linking against libsupc++_nano.a and it has worked great.  However, we've found that it does not work for throwing C++ exceptions.  The problem appears to be none of the ARM.exidx or ARM.extab linker sections are generated during the build of libsupc++_nano; if you use the arm-none-eabi-objdump tool you can see that none of the sections are there vs. for the full libsupc++.a library they are all over the place.

It's unfortunate that the exception tables aren't being built as part of libsupc++_nano.a because it apparently contains all of the exception-handling/unwinding code and links just fine when you try to use it in a program that throw exceptions.  What happens in this case is that __cxa_throw() is invoked by a C++ "throw" statement and then the stack unwinding code tries to look up the EIT entry for a return address in __cxa_throw().  However, since libsupc++_nano was built without exception tables, no such EIT entry exists and std::terminate() is invoked instead.

When we link against the full libsupc++.a, exceptions do work.  However, this has the downside of pulling in a huge amount of extra code that we really don't care about.  It seems like C++ name demangling gets pulled in and this bloats the binary by nearly 30K.  I think this is because the full libsupc++ tries to write exception information to STDOUT whereas libsupc++_nano is silent.  When linking against the full libsupc++ we also have to provide things like _read, _write, _lseek, _isatty, etc. - I think all so that std::terminate() can print something like "uncaught exception of type foo::bar::baz" before aborting.

We think it would be really great if libsupc++_nano.a could be built such that exception handling tables are also included in the library.  The exception tables themselves wouldn't significantly change the size of the binary, and they can be discarded by the linker for users that do not use exception handling code.

TG

  • Since we are also using C++-exceptions:

    To remove the "30K" code blob, just override the default terminate handler:

    namespace __cxxabiv1 {
    
    // Override default terminate handler to just abort.
    std::terminate_handler __terminate_handler = std::abort;
    
    }    // namespace __cxxabiv1

    This should resolve your problems.

  • FWIW, 2 years later I've revisited this and built versions of gcc with exception-handling support enabled in nano_eh libraries that parallel the nano libraries.  Dockerfiles and release binaries are available on github:

    https://github.com/tgree/docker-gcc-arm-none-eabi-nano_eh-build

    I've also released a repository to build Docker containers that have the gcc compiler inside the container that you can use to bind-mount and build source trees that live outside of Docker, for instance to build local sources if you are using Docker for Mac or Docker for Windows:

    https://github.com/tgree/docker-gcc-arm-none-eabi

    This allows you to have many different versions of gcc, including nano_eh and non-nano_eh versions all available side-by-side.  Hopefully these will be of use to others attempting to use exceptions with the nano libraries.

    TG