Обновление 2016-12 В настоящее время также существует минимальный пример такого поведения: https://community.nxp.com/message/862676
Я использую ARM Cortex M4 с freertos, используя свободу свободного времени. Kinetis IDE (gnu arm toolchain). Проблема в том, что
try {
throw 4; // old scenario also not working: throw std::runtime_error("wut");
} catch (...) {
}
приводит к остановке CPU и кода после попытки или (когда некоторые добавлены) в обработчике catch не выполняется.
И сборку можно найти здесь: https://gist.github.com/Superlokkus/3c4201893b4c51e154e2a0afdf78fef0
Я ПРИНИМАЮ, что это приводит к прерыванию SVC, извините, что я ошибался, Freertos обманул меня в этом, потому что, когда я бросаю что-то, это останавливается в DefaultISR.
Бросок действительно переходит на __ cxa_throw, а затем оттуда до ___Unwind_RaiseException __gnu_Unwind_RaiseException __cxa_begin_catch > < _ZSt9terminatev >
Таким образом, похоже, что вызывается std::terminate
, но блокировка catch не должна этого допускать. Или мое предположение неверно, и это поведение объясняется тем, что поддержка исключений во время выполнения gcc С++ - это заглушка, которая всегда вызывает завершение?!
Обновление 2016-09. Поскольку я видел, что rand() пытается использовать malloc(), я также определил рабочую функцию malloc()/freeRTOS и et voilà: __cxa_allocate_exception использует malloc (мне интересно как toolchain ожидает, что я обработать случай 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>
Если вам интересно или это может помочь: мои отладчики говорят, что у меня есть WDOG_EWM_IRQHandler, если я не определяю обработчик hard_fault и собственный обработчик по умолчанию.
Итак, я думаю, что что-то пошло не так в раскрутке стека, потому что я прохожу через некоторые символы с "завершенным стеком" в имени в _throw, но я не нашел точку прерывания, которую я установил в деструкторе объекта, который должны были быть очищены. И это, по-видимому, мотивирует __cxa_begin_catch на вызов прерывания или что-то в этом роде.
(Kinetis Design Studio 3.2.0. с Перекрестный компилятор GNU ARM C/С++ Версия: 1.12.1.201502281154 для нашего FRDM-KV31F)