Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 14 Oct 2018 00:40:27 -0700
From:      Mark Millard <marklmi@yahoo.com>
To:        FreeBSD PowerPC ML <freebsd-ppc@freebsd.org>
Subject:   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)
Message-ID:  <0539C16B-1603-4639-914A-0308578C7262@yahoo.com>
In-Reply-To: <E1167EAA-3F90-4F0A-9F51-53CFE1461617@yahoo.com>
References:  <E1167EAA-3F90-4F0A-9F51-53CFE1461617@yahoo.com>

next in thread | previous in thread | raw e-mail | index | archive | help
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).]
>=20
> booting, buildworld, buildkernel, poudriere building
> what totaled to be somewhat under 400 ports all seem
> to work. But . . .
>=20
> 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 :
>=20
> Such code ends up stuck using around 100% of a CPU.
> An example is the program:
>=20
> # more exception_test.cpp
> #include <exception>
>=20
> int main(void)
> {
>    try { throw std::exception(); }
>    catch (std::exception& e) {}
>    return 0;
> }
>=20
> For system-clang it ended up with:
>=20
> # ldd a.out
> a.out:
> 	libc++.so.1 =3D> /usr/lib/libc++.so.1 (0x81006d000)
> 	libcxxrt.so.1 =3D> /lib/libcxxrt.so.1 (0x810184000)
> 	libm.so.5 =3D> /lib/libm.so.5 (0x8101ab000)
> 	libc.so.7 =3D> /lib/libc.so.7 (0x8101eb000)
> 	libgcc_s.so.1 =3D> /lib/libgcc_s.so.1 (0x810554000)
>=20
> That program goes into an possibly unbounded execution.
> (Historically when this program had problems it would
> stop and produce a core file.)
>=20
> When compiled by devel/powerpc64-gcc the a.out that results
> does the same thing. ( =
/usr/local/bin/powerpc64-unknown-freebsd12.0-c++=20
> as the compiler path ) So this is not really clang specific
> in any way. This ended up with:
>=20
> # ldd a.out
> a.out:
> 	libc++.so.1 =3D> /usr/lib/libc++.so.1 (0x81006d000)
> 	libcxxrt.so.1 =3D> /lib/libcxxrt.so.1 (0x810184000)
> 	libm.so.5 =3D> /lib/libm.so.5 (0x8101ab000)
> 	libgcc_s.so.1 =3D> /lib/libgcc_s.so.1 (0x8101eb000)
> 	libc.so.7 =3D> /lib/libc.so.7 (0x810211000)
>=20
> (That should not have involved clang or llvm at all.)
>=20
> But compiled by lang/gcc8's g++8 the a.out that results works
> fine. This ends up with:
>=20
> # ldd a.out
> a.out:
> 	libstdc++.so.6 =3D> /usr/local/lib/gcc8/libstdc++.so.6 =
(0x81006e000)
> 	libm.so.5 =3D> /lib/libm.so.5 (0x8102c7000)
> 	libgcc_s.so.1 =3D> /lib/libgcc_s.so.1 (0x810307000)
> 	libc.so.7 =3D> /lib/libc.so.7 (0x81032d000)
>=20
> 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 .
>=20
> It will probably be some time before I figure out
> much about what is going on.
>=20
> Two things common to the problem cases are:
>=20
> libc++.so.1 =3D> /usr/lib/libc++.so.1 (0x81006d000)
> libcxxrt.so.1 =3D> /lib/libcxxrt.so.1 (0x810184000)
>=20
> lang/gcc8 avoids those being involved.
>=20
>=20
> Notes:
>=20
> 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.
>=20
> WITHOUT_LIB32=3D 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.
>=20
> 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.=20

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;
    =20
  /* Set up this_context to describe the current stack frame.  */
  uw_init_context (&this_context);
  cur_context =3D this_context;
     =20
  /* 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;
       =20
      /* Set up fs to describe the FDE for the caller of cur_context.  =
The
         first time through the loop, that means __cxa_throw.  */
      code =3D uw_frame_state_for (&cur_context, &fs);

NOTE: code =3D=3D _URC_NO_REASON always results

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

      if (code !=3D _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 =3D (*fs.personality) (1, _UA_SEARCH_PHASE, =
exc->exception_class,
                                    exc, &cur_context);
          if (code =3D=3D _URC_HANDLER_FOUND)
            break;
          else if (code !=3D _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 =3D 0;
  exc->private_2 =3D uw_identify_context (&cur_context);

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

  uw_install_context (&this_context, &cur_context);
}


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




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?0539C16B-1603-4639-914A-0308578C7262>