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;


Reply via email to