简体   繁体   English

gnu arm cortex m4上的C ++异常处理程序,带有freertos

[英]C++ exception handler on gnu arm cortex m4 with freertos

Update 2016-12 There is now also a minimal example for this behavior: https://community.nxp.com/message/862676 更新2016-12此行为现​​在还有一个最小的示例: https//community.nxp.com/message/862676


I'm using a ARM Cortex M4 with freertos using freescales freedom Kinetis IDE (gnu arm toolchain). 我正在使用ARM Cortex M4和freertos使用freescales自由Kinetis IDE(gnu arm工具链)。 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. 在try处理程序之后导致暂停的CPU和代码,或者在catch处理程序中(当添加一些代码时)不会执行。

And assembly can be found here: https://gist.github.com/Superlokkus/3c4201893b4c51e154e2a0afdf78fef0 可以在这里找到汇编: 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. 我认为这会导致SVC中断,我很抱歉我弄错了,Freertos欺骗了我,因为当我扔东西时它会在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. throw indeeds跳转到__cxa_throw然后从那里___Unwind_RaiseException __gnu_Unwind_RaiseException __cxa_begin_catch> <_ZSt9terminatev>所以它看起来像是调用了std::terminate ,但是catch all块不应该允许这个。 Or is my assumption wrong and this behavior is because the gcc C++ runtime exception support is a stub which always calls terminate?! 或者我的假设是错误的,这种行为是因为gcc C ++运行时异常支持是一个总是调用终止的存根?!

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). 更新2016-09 :因为我看到rand()尝试使用malloc(),我还定义了一个工作的malloc()/ freeRTOS函数和etvoilà:__ cxa_allocate_exception使用malloc(我想知道工具链是如何期望我处理bad_alloc的情况)。 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. 如果你想知道它可能会有所帮助:我的调试器说它的WDOG_EWM_IRQHandler崩溃了,如果我没有定义hard_fault处理程序和一个自己的默认处理程序。

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. 所以我想在堆栈展开时出现了问题,因为我在_throw的名称中通过一些带有“完成堆栈展开”的符号,但是我没有抓住我在一个对象的析构函数中设置的断点本应该是清理干净了。 And that seems to motivate __cxa_begin_catch to call abort or something. 这似乎激励__cxa_begin_catch调用中止或其他东西。

( Kinetis Design Studio 3.2.0. with the GNU ARM C/C++ Cross Compiler Version: 1.12.1.201502281154 for our FRDM-KV31F) (Kinetis Design Studio 3.2.0。使用GNU ARM C / C ++交叉编译器版本:1.12.1.201502281154用于我们的FRDM-KV31F)

By fault, most of your exceptions will execute the default handler, so the first thing you need to do is determine which exception is actually executing. 由于错误,大多数异常都将执行默认处理程序,因此您需要做的第一件事是确定实际执行的异常。 You can see the "Determining Which Exception Handler is Executing" section on the following page: http://www.freertos.org/Debugging-Hard-Faults-On-Cortex-M-Microcontrollers.html 您可以在下面的页面中看到“确定哪个异常处理程序正在执行”部分: http//www.freertos.org/Debugging-Hard-Faults-On-Cortex-M-Microcontrollers.html

I would guess, since you are not using a peripheral in your code, that it will be a fault handler, probably the hard fault. 我猜,因为你没有在你的代码中使用外围设备,它将是一个故障处理程序,可能是硬故障。 The same page (see link above) gives instructions on debugging that too. 同一页面(参见上面的链接)也提供了有关调试的说明。

Other than that - ensure you do the normal FreeRTOS debug things, like ensure you have configASSERT() defined, and that you have stack overflow checking on. 除此之外 - 确保您执行正常的FreeRTOS调试,例如确保您定义了configASSERT(),并且您已经进行了堆栈溢出检查。 Info on those topics is found on this page: http://www.freertos.org/FAQHelp.html 有关这些主题的信息,请访问此页面: http//www.freertos.org/FAQHelp.html

From the RTOS side of things, C++ exceptions are just a glorified jump. 从RTOS方面来看,C ++异常只是一个美化的跳跃。 As long as they're jumping from one bit of your code to another, they don't interfere with the RTOS. 只要它们从您的代码的一个位跳到另一个,它们就不会干扰RTOS。 So you can write a try { } catch(std::exception) { } . 所以你可以写一个try { } catch(std::exception) { }

When there is no C++ handler, the RTOS indeed will have to step in as your C++ code stops running. 没有 C ++处理程序时,当您的C ++代码停止运行时,RTOS确实必须介入。

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: 在freescales Kinetis中成功创建一个具有默认设置的空白项目,并在nxp社区中提出同样的问题后 ,恩智浦工程师Alice_Yang(假设通过NXP徽章)告诉我答案:

By default new projects link to newlib-nano which has it exception support disabled. 默认情况下,新项目链接到newlib-nano,禁用异常支持。

The libstdc++ built along with newlib-nano have exception handling disabled. 与newlib-nano一起构建的libstdc ++禁用了异常处理。

So the solution is to link simply to newlib. 所以解决方案是简单地链接到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. 这可以通过简单地删除“其他链接器标志”中的“-specs = nano.specs”行来完成,并确保也禁用添加相同选项的复选框。 Then everything works as expected. 然后一切都按预期工作。 Only the code increased by 27 kB in ROM/text size and 2kB in RAM/data. 只有代码在ROM /文本大小上增加了27 kB,在RAM /数据中增加了2kB。 在此输入图像描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM