GCC arm-none-eabi (Codesourcery) and C++ Exceptions
Asked Answered
C

1

6

I am using Raisonance's Ride7/Codesourcery (a.k.a Sourcery CodeBench Lite) with an STM32F4 board developing a bare metal HMI platform.

I will be making use of C++ exceptions in this system, but any exception I throw ends with a "Terminate called recursively" error written to stderr.

Code to reproduce the problem: (main.cpp)

int main(void)
{
    try {
        throw 1;
    }
    catch (...) {
        printf("caught");
    }
}

I've already tried Raisonance and other sources for a resolution, and have not received any actionable help.

Potential problem/solution 1:

I've asked on other forums and they mention I need to call static constructions in my startup assembly file to initialize the unwind tables (at least that's what I think they are talking about), but I have no idea how to do this.

Potential problem/solution 2

I have also discovered a bug in binutils/gas that may be the source of my problems here (http://sourceware.org/bugzilla/show_bug.cgi?id=13449). I've been trying to build my own version of the toolchain with this patch, but that's turning into a project of its own, and have not yet succeeded.

The Question

Do I need to do something in code to make use of C++ exceptions, or is this likely a bug in the toolchain? If the former, please elaborate.

Clownery answered 28/8, 2012 at 0:42 Comment(14)
Very few embedded toolchains support exceptions properly, if at all. In my opinion, using exceptions in embedded software is a bad idea.Milan
@IgorSkochinsky I knew someone was going to say that. Codesourcery's documentation clearly states support for C++ exceptions. I know my requirements and I know that using exceptions is the right decision for my project, but that's irrelevant to the question at hand.Clownery
@verax which libc are you linked against? I wonder whether you have a mismatch?Bernie
Do you get the same behaviour with the printf() removed? i.e. is the call to printf() rethrowing for some reason on that runtime?Submission
@Marko The libc I have is the one that came with CodeSourcery, I believe it's newlib. Maybe you could elaborate more on what you mean by "mismatch". I know my printf is working as it works fine if I remove the exception handling code and just print a simple "hello world". If I leave the catch block empty, the result is the same. I think the error is actually occurring at the throw.Clownery
@verax a fair bit of the exception mechanism is implemented in the runtime library. The initialisation of the library (as suggested by others) is a good place to look. I guess if you've got a bare metal system, it's possibly not called at all unless you've done it explicitly.Bernie
@Marko It's my understanding the exception handling stuff is actually in libsupc++, which gets automatically linked with libstdc++. I've tried linking to libstdc++, libsupc++, libc, and all of them together with no luck. If there's some initialization I have to do I'd sure like to know what it is.Clownery
How are you linking this? i.e. are you using gcc, g++, or a custom linker line? (Linking with g++ does a lot of magic to make strange C++ features work, so if you're not using that, try it and see what happens.)Lail
@DavidGiven Actually I'm linking with gcc since that is what the Ride7 IDE does. I tried with g++ but got the same results.Clownery
@DavidGiven, linking with g++ just passes -lstdc++ -lm to the linker, not much magic.Albania
@JonathanWakely Not always; it depends on the platform, particularly for weird embedded platforms.Lail
Try enabling -fexceptions explicitly. It's supposed to be enabled by default for C++, but if your build system uses gcc for some things, instead of g++, there might be trouble.Seltzer
@Seltzer I tried -fexceptions and using g++ instead of gcc. Still not luck.Clownery
The patch looks like it might DTRT, but building cross toolchains is a black art. That's why everyone uses CS toolchains. :) There'll be a new one out in a month or two. You might have more luck then.Seltzer
C
2

After some persuasion that shouldn't have been necessary, Raisonance finally came through with a modification to their default linker script that fixed the problem. It may not be legal for me to post the entire linker script, but here's the knowledge that one needs to know

Add this to the .text section

*(.eh_frame)

Add these sections (name YourMemory according to the memory blocks you've set up in your linker script. Mine was Flash)

.ARM.extab :
{
    *(.ARM.extab* .gnu.linkonce.armextab.*)
} >YourMemory

.ARM :
{
    __exidx_start = .;
    *(.ARM.exidx*)
    __exidx_end = .;
} >YourMemory

Ensure this line occurs in the bss section

*(.bss*)

While on this quest, I ran across the following useful resources

Clownery answered 31/8, 2012 at 1:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.