2016 年 12 月更新现在还有一个关于此行为的最小示例:https://community.nxp.com/message/862676 https://community.nxp.com/message/862676
我正在使用带有 freertos 的 ARM Cortex M4,使用 Freescales Freedom Kinetis IDE(gnu arm 工具链)。问题是
try {
throw 4; // old scenario also not working: throw std::runtime_error("wut");
} catch (...) {
}
导致 CPU 停止,并且 try 后的代码或(添加一些代码时)catch 处理程序中的代码不会执行。
可以在这里找到组装:https://gist.github.com/Superlokkus/3c4201893b4c51e154e2a0afdf78fef0 https://gist.github.com/Superlokkus/3c4201893b4c51e154e2a0afdf78fef0
我认为这会导致 SVC 中断,很抱歉我弄错了,Freertos 欺骗了我,因为当我抛出一些东西时,它会在 DefaultISR 中停止。
投掷确实跳到__cxa_throw 然后从那里到 ___Unwind_RaiseException __gnu_Unwind_RaiseException __cxa_begin_catch>
<_zst9>所以看起来像std::terminate
被调用,但 catch all 块不应允许这样做。或者我的假设是错误的,这种行为是因为 gcc C++ 运行时异常支持是一个总是调用终止的存根?!
更新2016-09:因为我看到 rand() 尝试使用 malloc(),所以我还定义了一个工作的 malloc()/freeRTOS 函数,等等:__cxa_allocate_exception 使用 malloc (我想知道工具链如何期望我处理 bad_alloc 情况)。
所以现在,它仍然崩溃,但是在异常分配之后(我认为):
执行路径为:
(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>
如果您想知道或者它可能有帮助:如果我没有定义hard_fault处理程序和自己的默认处理程序,我的调试器会说它是我崩溃的WDOG_EWM_IRQHandler。
所以我猜想堆栈展开中出了问题,因为我在 _throw 中遍历了一些名称中带有“完成的堆栈展开”的符号,但我没有捕获我在对象的析构函数中设置的断点,该断点应该是清理干净了。这似乎促使 __cxa_begin_catch 调用 abort 或其他东西。
( Kinetis Design Studio 3.2.0。
GNU ARM C/C++ 交叉编译器
版本:1.12.1.201502281154
为了我们的
FRDM-KV31F)