Hi all, The bug is reported at https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56846, and it’s about the problem that when exception handler is involved in the function, then _Unwind_Backtrace function will run into deadloop on arm target.
Cmd line: arm-none-eabi-g++ -mthumb -mcpu=cortex-m3 -O0 -g -std=c++11 -specs=rdimon.specs main.c -o main.exe #include <unwind.h> #include <stdio.h> _Unwind_Reason_Code trace_func(struct _Unwind_Context * context, void* arg) { void *ip = (void *)_Unwind_GetIP(context); printf("Address: %p\n", ip); return _URC_NO_REASON; } void bar() { puts("This is in bar"); _Unwind_Backtrace((_Unwind_Trace_Fn)&trace_func, 0); } void foo() { try { bar(); } catch (...) { puts("Exception"); } } The potential of such a bug is discussed long time ago in mail: https://gcc.gnu.org/ml/gcc/2007-08/msg00235.html. Basically, as the ARM EHABI does not define how to implement the Unwind_Backtrace, Andrew give control to the personality routine to unwind the stack, and use the unwind state combination of “_US_VIRTUAL_UNWIND_FRAME | _US_FORCE_UNWIND” to represent that the caller is asking the personality routine to only unwind the stack for it. However, the pr in the libstdc++-v3 doesn’t handle such a unwind state pattern correctly. When the backtrace function passes such a pattern to it, it will still return _URC_HANDLER_FOUND to the caller in some cases. It’s because the pr will think that the _Unwind_Backtrace is raising a none type exception to it, so if the exception handler in current stack frame can catch anything(like catch(…)), the pr will return _URC_HANDLER_FOUND to the caller and ask for next step. But definitely, the unwind backtrace function don’t know what to do when pr return an exception handler to it. So this patch just evaluate such a unwind state pattern at the beginning of the personality routine in libstdc++-v3, if we meet with “_US_VIRTUAL_UNWIND_FRAME | _US_FORCE_UNWIND”, then we directly call macro CONTINUE_UNWINDING to unwind the stack and return. Is this a reasonable fix? gcc/libstdc++-v3/ChangeLog: 2014-8-25 Tony Wang <tony.w...@arm.com> PR target/56846 * libsupc++/eh_personality.cc: Return with CONTINUE_UNWINDING when meet with the unwind state pattern: _US_VIRTUAL_UNWIND_FRAME | _US_FORCE_UNWIND diff --git a/libstdc++-v3/libsupc++/eh_personality.cc b/libstdc++-v3/libsupc++/eh_personality.cc index f315a83..c2b30e9 100644 --- a/libstdc++-v3/libsupc++/eh_personality.cc +++ b/libstdc++-v3/libsupc++/eh_personality.cc @@ -378,6 +378,11 @@ PERSONALITY_FUNCTION (int version, switch (state & _US_ACTION_MASK) { case _US_VIRTUAL_UNWIND_FRAME: + // If the unwind state pattern is _US_VIRTUAL_UNWIND_FRAME | + // _US_FORCE_UNWIND, we don't need to search for any handler + // as it is not a real exception. Just unwind the stack. + if (state & _US_FORCE_UNWIND) + CONTINUE_UNWINDING; actions = _UA_SEARCH_PHASE; break;