带有 freertos 的 gnu arm cortex m4 上的 C++ 异常处理程序 [英] C++ exception handler on gnu arm cortex m4 with freertos

查看:23
本文介绍了带有 freertos 的 gnu arm cortex m4 上的 C++ 异常处理程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

2016-12 更新现在还有一个针对此行为的最小示例:

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)

解决方案

After successfully creating a blank project with default settings in freescales Kinetis, and asking the same problem on the nxp community, Alice_Yang , an NXP engineer (assuming by the NXP badge), told me the answer:

By default new projects link to newlib-nano which has it exception support disabled.

The libstdc++ built along with newlib-nano have exception handling disabled.

So the solution is to link simply to newlib. This can be done by simply removing the line "-specs=nano.specs" in "other linker flags" and also make sure the check box which adds the same option is also disabled. Then everything works as expected. Only the code increased by 27 kB in ROM/text size and 2kB in RAM/data.

这篇关于带有 freertos 的 gnu arm cortex m4 上的 C++ 异常处理程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆