Re: FYI: powerpc64 headbuilt via devel/powerpc64-xtoolchain-gcc and C++ exceptions for user code built by system-clang or devel/powerpc64-gcc (as of head -r339076 and ports -r480180)

Mark Millard via freebsd-ppc <[email protected]>
Newsgroups gmane.os.freebsd.devel.ppc
Message-ID <[email protected]>
On 2018-Oct-12, at 1:59 PM, Mark Millard <marklmi at yahoo.com> wrote:

> I built a powerpc64 head -r339076 via devel/powerpc64-gcc
> and the like that built clang as cc as well (and
> WITHOUT_LIB32). This included use of base/binutils to
> the the powerpc64 set up. The system and kernel are
> non-debug builds (but with symbols). [system-clang is not
> used for buildworld buildkernel because of known
> issues (last I tried).]
> 
> booting, buildworld, buildkernel, poudriere building
> what totaled to be somewhat under 400 ports all seem
> to work. But . . .
> 
> It been a long time since I've done something analogous
> and a significant item in the result is different than in
> the past once I started testing the throwing of C++
> exceptions in code produced by system-clang or by
> devel/powerpc64-gcc :
> 
> Such code ends up stuck using around 100% of a CPU.
> An example is the program:
> 
> # more exception_test.cpp
> #include <exception>
> 
> int main(void)
> {
>    try { throw std::exception(); }
>    catch (std::exception& e) {}
>    return 0;
> }
> 
> For system-clang it ended up with:
> 
> # ldd a.out
> a.out:
> 	libc++.so.1 => /usr/lib/libc++.so.1 (0x81006d000)
> 	libcxxrt.so.1 => /lib/libcxxrt.so.1 (0x810184000)
> 	libm.so.5 => /lib/libm.so.5 (0x8101ab000)
> 	libc.so.7 => /lib/libc.so.7 (0x8101eb000)
> 	libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x810554000)
> 
> That program goes into an possibly unbounded execution.
> (Historically when this program had problems it would
> stop and produce a core file.)
> 
> When compiled by devel/powerpc64-gcc the a.out that results
> does the same thing. ( /usr/local/bin/powerpc64-unknown-freebsd12.0-c++ 
> as the compiler path ) So this is not really clang specific
> in any way. This ended up with:
> 
> # ldd a.out
> a.out:
> 	libc++.so.1 => /usr/lib/libc++.so.1 (0x81006d000)
> 	libcxxrt.so.1 => /lib/libcxxrt.so.1 (0x810184000)
> 	libm.so.5 => /lib/libm.so.5 (0x8101ab000)
> 	libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x8101eb000)
> 	libc.so.7 => /lib/libc.so.7 (0x810211000)
> 
> (That should not have involved clang or llvm at all.)
> 
> But compiled by lang/gcc8's g++8 the a.out that results works
> fine. This ends up with:
> 
> # ldd a.out
> a.out:
> 	libstdc++.so.6 => /usr/local/lib/gcc8/libstdc++.so.6 (0x81006e000)
> 	libm.so.5 => /lib/libm.so.5 (0x8102c7000)
> 	libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x810307000)
> 	libc.so.7 => /lib/libc.so.7 (0x81032d000)
> 
> It is not clear if using base/gcc as system cc
> would do any better than using system-clang does
> or than devel/powerpc64-gcc does: it is sort of
> a variant of devel/powerpc64-gcc .
> 
> It will probably be some time before I figure out
> much about what is going on.
> 
> Two things common to the problem cases are:
> 
> libc++.so.1 => /usr/lib/libc++.so.1 (0x81006d000)
> libcxxrt.so.1 => /lib/libcxxrt.so.1 (0x810184000)
> 
> lang/gcc8 avoids those being involved.
> 
> 
> Notes:
> 
> Some time ago I'd used system-clang to build such
> programs in an environment built via devel/powerpc64-gcc
> and devel/powerpc64-binutils and the programs worked.
> The same for devel/powerpc64-gcc use: the code it
> produced for the programs also worked. At this point
> I've no clue what changed or when.
> 
> WITHOUT_LIB32= is because, for every post-gcc 4.2.1
> that I've tried, the lib32 produced misuses R30 in
> crtbeginS code (vs. the ABI for FreeBSD) and 32-bit
> code just produces core files from the bad so-called
> address dereference that results.
> 
> I'd rather have throwing C++ exceptions working and
> lack of lib32 than have lib32 but not have throwing
> C++ exceptions working. But at the moment how to have
> such is not obvious when fairly modern compilers
> and toolchains are involved. 

Here is what I've found so far.

The code is looping in the following routine.
(I've inserted 2 NOTE: lines for what the
sustained looping is like.)

_Unwind_Reason_Code
_Unwind_RaiseException(struct _Unwind_Exception *exc)
{
  struct _Unwind_Context this_context, cur_context;
  _Unwind_Reason_Code code;
     
  /* Set up this_context to describe the current stack frame.  */
  uw_init_context (&this_context);
  cur_context = this_context;
      
  /* Phase 1: Search.  Unwind the stack, calling the personality routine
     with the _UA_SEARCH_PHASE flag set.  Do not modify the stack yet.  */
  while (1)
    {
      _Unwind_FrameState fs;
        
      /* Set up fs to describe the FDE for the caller of cur_context.  The
         first time through the loop, that means __cxa_throw.  */
      code = uw_frame_state_for (&cur_context, &fs);

NOTE: code == _URC_NO_REASON always results

      if (code == _URC_END_OF_STACK)
        /* Hit end of stack with no handler found.  */
        return _URC_END_OF_STACK;

      if (code != _URC_NO_REASON)
        /* Some error encountered.  Ususally the unwinder doesn't
           diagnose these and merely crashes.  */
        return _URC_FATAL_PHASE1_ERROR;

      /* Unwind successful.  Run the personality routine, if any.  */
      if (fs.personality)
NOTE: fs.personality never evaluates to true
        {
          code = (*fs.personality) (1, _UA_SEARCH_PHASE, exc->exception_class,
                                    exc, &cur_context);
          if (code == _URC_HANDLER_FOUND)
            break;
          else if (code != _URC_CONTINUE_UNWIND)
            return _URC_FATAL_PHASE1_ERROR;
        }

      /* Update cur_context to describe the same frame as fs.  */
      uw_update_context (&cur_context, &fs);
    }

  /* Indicate to _Unwind_Resume and associated subroutines that this
     is not a forced unwind.  Further, note where we found a handler.  */
  exc->private_1 = 0;
  exc->private_2 = uw_identify_context (&cur_context);

  cur_context = this_context;
  code = _Unwind_RaiseException_Phase2 (exc, &cur_context);
  if (code != _URC_INSTALL_CONTEXT)
    return code;

  uw_install_context (&this_context, &cur_context);
}


===
Mark Millard
marklmi at yahoo.com
( dsl-only.net went
away in early 2018-Mar)

_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/freebsd-ppc
To unsubscribe, send any mail to "[email protected]"
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.