Update 2016-12 There is now also a minimal example for this behavior: https://community.nxp.com/message/862676
I'm using a ARM Cortex M4 with freertos using freescales freedom Kinetis IDE (gnu arm toolchain). Problem is that
try {
throw 4; // old scenario also not working: throw std::runtime_error("wut");
} catch (...) {
}
results in a halted CPU and code after the try or (when some is added) in the catch handler is not executed.
And assembly can be found here: https://gist.github.com/Superlokkus/3c4201893b4c51e154e2a0afdf78fef0
I ASSUMED that this results in an SVC interrupt, I'm sorry I got that wrong, Freertos tricked me into this, because when I throw something it halts in DefaultISR.
The throw indeeds jump to __cxa_throw then from there to ___Unwind_RaiseException __gnu_Unwind_RaiseException __cxa_begin_catch>
<_ZSt9terminatev>
So it looks like std::terminate
is called, but the catch all block should not allow this. Or is my assumption wrong and this behavior is because the gcc C++ runtime exception support is a stub which always calls terminate?!
Update 2016-09: Because I saw that rand() tries to use malloc(), I also defined a working malloc()/freeRTOS function and et voilà: __cxa_allocate_exception uses malloc (I wonder how the toolchain expects me to handle a bad_alloc case). So now, it still crashes, but after exception allocation (I think): The excecution path is :
(throwing function after exception allocation)
__cxa_throw
... //(some intructions in __cxa_throw)
__cxa_begin_catch //I guess something went wrong here
_ZSt9terminatev // Immediately after __cxa_begin_catch
_ZN10__cxxabiv111__terminateEPFvvE:
00016dfc: push {r3, lr}
00016dfe: blx r0 //Goes directly to WDOG_EWM_IRQHandler or hard fault handler
00016e00: bl 0x194ac <abort>
If you wonder or it might help: My debuggers say its the WDOG_EWM_IRQHandler I crash into, if I not define the hard_fault handler and an own default handler.
So I guess something went wrong in the stack unwinding, because I go thru some symbols with "finished stack unwinding" in the name in _throw, but I didn't catched the break point I set in a destructor of an object which should have been cleaned up. And that seems to motivate __cxa_begin_catch to call abort or something.
( Kinetis Design Studio 3.2.0. with the GNU ARM C/C++ Cross Compiler Version: 1.12.1.201502281154 for our FRDM-KV31F)
SVC_Handler
above FreeRTOS' that can check why it got there.SVC
takes a parameter that ends up inR0
IIRC, and FreeRTOS by default callsSVC #0
, so depending on what gcc is inserting for theSVC
parameter you may be able to distinguish the source. It will block RTOS interrupts as you fear though. – rjp