nuttx: PolarFire SoC - C++ Exception Exits Before Catch
Summary
On the PolarFire Icicle board, when building from master with a config based on icicle:nsh (plus config and flag changes detailed below), the cxxtest built-in app exception test fails. It throws the exception and then exits without catching the exception.
I’ve tried this on both the Icicle board and a PolarFire Renode simulation. I’m building with riscv-none-elf-* from xPack: gcc version 13.2.0 (xPack GNU RISC-V Embedded GCC x86_64).
I’m hoping someone knows what the issue might be as I’m not familiar with the behind the scenes of exception handling. Meanwhile I’ll keep working on this.
Config
Changed optimization to -Og for debugging and set -mstrict-align to prevent a crash due to misaligned instructions.
Ran make savedefconfig and the following. The task size configs are set because I had to increase CONFIG_DEFAULT_TASK_STACKSIZE to prevent a stack overflow during exception unwinding.
$ diff boards/risc-v/mpfs/icicle/configs/nsh/defconfig defconfig
9a10,12
> # CONFIG_NSH_DISABLE_MB is not set
> # CONFIG_NSH_DISABLE_MH is not set
> # CONFIG_NSH_DISABLE_MW is not set
21a25,26
> CONFIG_CXX_EXCEPTION=y
> CONFIG_CXX_RTTI=y
25a31
> CONFIG_DEFAULT_TASK_STACKSIZE=32768
30a37
> CONFIG_HAVE_CXX=y
34a42,43
> CONFIG_LIBCXX=y
> CONFIG_LIBCXXABI=y
37a47
> CONFIG_LIBM=y
50a61
> CONFIG_POSIX_SPAWN_DEFAULT_STACKSIZE=2048
51a63
> CONFIG_PTHREAD_STACK_DEFAULT=2048
58a71
> CONFIG_SCHED_HPWORKSTACKSIZE=2048
59a73
> CONFIG_SCHED_LPWORKSTACKSIZE=2048
66a81
> CONFIG_SYSTEM_NSH_STACKSIZE=2048
68a84
> CONFIG_TESTING_CXXTEST=y
69a86
> CONFIG_TESTING_GETPRIME_STACKSIZE=2048
70a88,89
> CONFIG_TESTING_OSTEST_FPUSTACKSIZE=2048
> CONFIG_TLS_NELEM=4
About this issue
- Original URL
- State: open
- Created 4 months ago
- Comments: 17 (9 by maintainers)
I don’t use exceptions so no idea what’s going on
I made some progress on this today.
_Unwind_Find_FDEwas returning NULL because theunseen_objectslinked list wasn’t initialized. This linked list needs to be initialized at startup, and then during exception handling it has nodes added and moved intoseen_objects. The list is used for finding an FDE by program counter.Looks like users of libgcc can either link with
crtbegin.oor write their own calls to libgcc__register_frame_info*function. Thecrtstuff.cfile provides aframe_dummy()function which is supposed to be placed in the.init_arraysection by the linker, so that it gets invoked by the initialization logic pre-main. Thisframe_dummyfunction does the registration using__EH_FRAME_BEGIN__. The function was getting called by NuttXlib_cxx_initialize()but,__EH_FRAME_BEGIN__wasNULLso initialization didn’t happen.I hacked up the
Toolchain.defsfile to linkcrtbegin.oandcrtend.oso that I getframe_dummy. With a new .eh_frame section in the linker script,__EH_FRAME_BEGIN__points to the beginning of.eh_frameand initialization works.The next problem is that during libgcc FDE searching, I get a RISC-V load address misaligned crash. I’m not sure what to do about this yet.
Hi @sastel that is very interesting investigation. If you can, please write down about it in some blog, probably it will help more people in the future.
@sastel maybe you can look some other board with C++ support to trace the differences, probably there some other details. Also if you could try in some ARM (like STM32F4Discovery board) it could help to see if everything still working as expected.