This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Divide_1 testsuite fail due to a problem in the unwinding code


Hi,

while debugging the java failure Divide_1 on s390 I stumbled over
some weird behaviour in the unwinding code.

In the testcase a divide by zero is triggered intentionally. So that
the java sigfpe handler is invoked in __divdi3:

Divide_1::probe_1() -> __divdi3
                           |SIGFPE
                           V  
			catch_fpe   -> _Jv_Throw

After doing the instruction parsing in order to figure out whether
it's actually the INT_MIN/-1 case or not an exception is thrown.

During _Unwind_RaiseException the handler is found in probe_1 and in
order to re-find it in phase2 the CFA! is recorded in the private_2 field
of the exception.

Starting with this IRA patch:
http://gcc.gnu.org/ml/gcc-patches/2011-10/msg00028.html
__divdi3 does *not* need a stack frame at all.

So the CFAs of __divdi3 and probe_1 are the same!

This triggers the assertion in _Unwind_RaiseException_Phase2 which
assumes that it is about to pass the frame with the handler without
actually finding one.


The CFA does not appear sufficient to identify the unwinding state. It
has been changed from using the IP with this patch:

http://gcc.gnu.org/ml/gcc-patches/2007-05/msg01252.html

Ulrich pointed out that also using the IP isn't a good choice since it
will fail in other circumstances (e.g. with recursive calls).  GDB
seems to use a combination of both (+a target specific value on some
architectures). We probably have to do similiar things here to fix this?!

Perhaps it would also be possible to just count the number of stack
frames in phase1 in order to use that information in phase2?! However,
I'm not sure whether invoking the destructors in phase2 could mess up
that information.

To my understanding this can only happen if there is control flow from
a leaf function which in turn should only occur with signals.  Perhaps
we could modify the CFA "a bit" for the frame where the signal
occurred?  There is already a hack in uw_identify_context which does
this for the signal frame:

static inline _Unwind_Ptr
uw_identify_context (struct _Unwind_Context *context)
{
  /* The CFA is not sufficient to disambiguate the context of a function
     interrupted by a signal before establishing its frame and the context
     of the signal itself.  */
  if (STACK_GROWS_DOWNWARD)
    return _Unwind_GetCFA (context) - _Unwind_IsSignalFrame (context);
  else
    return _Unwind_GetCFA (context) + _Unwind_IsSignalFrame (context);
}

Any ideas?

Bye,

-Andreas-


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]