Re: projects/clang380-import for TARGET_ARCH=powerpc64: /lib/libgcc_s.so.1 is incompatible with using the pair: /usr/lib/libc++.so.1 and /lib/libcxxrt.so.1 for C++ exception handling

2016-02-24 Thread Mark Millard
[In part: My references to libc++ should have been to libcxxrt. Also: 
devel/powerpc64-gcc produced the incomplete .eh_frame information.]

On 2016-Feb-24, at 5:07 PM, Mark Millard  wrote:
> 
> [Deliberate top posting an history removal for significant new information.]
> 
> I've finally traced the low level details of the powerpc64 
> _Unwind_RaiseException stuck looping failure.  What I've submitted into the 
> defect is basically that for clang 3.8.0's .eh_frame information generation 
> in libcxxrt's code there is an error in the form of an incompleteness. . .
> 
> 
> Starting from the observed low-level evidence based on observation via gdb 
> and such:
> 
> A backtrace while stopped during the unbounded looping is:
> 
>> #0  uw_update_context (context=context@entry=0xccf0, 
>> fs=fs@entry=0xc370) at 
>> /usr/src/gnu/lib/libgcc/../../../contrib/gcc/unwind-dw2.c:1371
>> #1  0x501cb95c in _Unwind_RaiseException (exc=0x50815058) at 
>> /usr/src/gnu/lib/libgcc/../../../contrib/gcc/unwind.inc:126
>> #2  0x5016e3a0 in throw_exception (ex=0x50815000) at 
>> /usr/src/lib/libcxxrt/../../contrib/libcxxrt/exception.cc:751
>> #3  0x1d50 in main () at exception_test.cpp:5
> 
> _Unwind_RaiseException never returns for source code that looks like:
> 
>> #include 
>> 
>> int main(void)
>> {
>>try { throw std::exception(); }
>>catch (std::exception& e) {}
>>return 0;
>> }
> 
> where in /usr/lib/libc++.so.1 there is:
> 
>> 736  static void throw_exception(__cxa_exception *ex)
>> 737  {
>> . . .
>> 751  _Unwind_Reason_Code err = 
>> _Unwind_RaiseException(>unwindHeader);
>> . . .
>> 756  }
> 
> The unbounded loop in _Unwind_RaiseException is in the code:
> 
>> 85   _Unwind_Reason_Code
>> 86   _Unwind_RaiseException(struct _Unwind_Exception *exc)
>> 87   {
>> 88 struct _Unwind_Context this_context, cur_context;
>> 89 _Unwind_Reason_Code code;
>> 90   
>> 91 /* Set up this_context to describe the current stack frame.  */
>> 92 uw_init_context (_context);
>> 93 cur_context = this_context;
>> 94   
>> 95 /* Phase 1: Search.  Unwind the stack, calling the personality routine
>> 96with the _UA_SEARCH_PHASE flag set.  Do not modify the stack yet.  
>> */
>> 97 while (1)
>> 98   {
>> 99 _Unwind_FrameState fs;
>> 100  
>> 101/* Set up fs to describe the FDE for the caller of cur_context.  
>> The
>> 102   first time through the loop, that means __cxa_throw.  */
>> 103code = uw_frame_state_for (_context, );
>> . . .
>> 125/* Update cur_context to describe the same frame as fs.  */
>> 126uw_update_context (_context, );
>> 127  }
>> . . .
>> 140  }
> 
> The uw_update_context call is doing the following before returning:
> 
>> 1367   /* Compute the return address now, since the return address column
>> 1368  can change from frame to frame.  */
>> 1369   context->ra = __builtin_extract_return_addr
>> 1370 (_Unwind_GetPtr (context, fs->retaddr_column));
> 
> with context->ra before and after the call both being 0x5016e3a0 . In fact it 
> was 0x5016e3a0 for the prior uw_frame_state_for call as well and continues to 
> be so each loop iteration once the problem starts.
> 
> As for the code around 0x5016e3a0:
> 
>>   0x5016e398 :stw 
>> r10,48(r9)
>>   0x5016e39c :bl  
>> 0x50162ae0 <0017.plt_call._Unwind_RaiseException@@GCC_3.0>
>>   0x5016e3a0 :ld  
>> r2,40(r1)
>>   0x5016e3a4 :addi
>> r1,r1,128
>>   0x5016e3a8 :mr  
>> r4,r31
>>   0x5016e3ac :ld  
>> r0,16(r1)
> 
> From /usr/local/bin/objdump for FreeBSD projects/clang380-import -r295902's 
> /usr/lib/libc++.so.1 for the same code (to match up with the .eh_frame dwarf 
> information):
> 
>> 00015398 <.__cxa_end_catch+0x4d8> stw r10,48(r9)
>> 0001539c <.__cxa_end_catch+0x4dc> bl  9ae0 
>> 
>> 000153a0 <.__cxa_end_catch+0x4e0> ld  r2,40(r1)
>> 000153a4 <.__cxa_end_catch+0x4e4> addir1,r1,128
>> 000153a8 <.__cxa_end_catch+0x4e8> mr  r4,r31
>> 000153ac <.__cxa_end_catch+0x4ec> ld  r0,16(r1)
> 
> The code block above from 153a0 up to 153a8 is being given 153a0 as its 
> "return address" (context->ra) by uw_update_context via interpreting the 
> dwarf .eh_frame information. So once in that range there it never leaves that 
> range.
> 
> The relevant dwarfdump output spanning that area is:
> (Note that 153a0 up to 153a8 is part of the range that includes the bl to 
> _Unwind_RaiseException .)
> 
>> <0><0x00015310:0x000153dc><>> 0x0034>
>>

Re: projects/clang380-import for TARGET_ARCH=powerpc64: /lib/libgcc_s.so.1 is incompatible with using the pair: /usr/lib/libc++.so.1 and /lib/libcxxrt.so.1 for C++ exception handling

2016-02-24 Thread Mark Millard
[Deliberate top posting an history removal for significant new information.]

I've finally traced the low level details of the powerpc64 
_Unwind_RaiseException stuck looping failure.  What I've submitted into the 
defect is basically that for clang 3.8.0's .eh_frame information generation in 
libcxxrt's code there is an error in the form of an incompleteness. . .


Starting from the observed low-level evidence based on observation via gdb and 
such:

A backtrace while stopped during the unbounded looping is:

> #0  uw_update_context (context=context@entry=0xccf0, 
> fs=fs@entry=0xc370) at 
> /usr/src/gnu/lib/libgcc/../../../contrib/gcc/unwind-dw2.c:1371
> #1  0x501cb95c in _Unwind_RaiseException (exc=0x50815058) at 
> /usr/src/gnu/lib/libgcc/../../../contrib/gcc/unwind.inc:126
> #2  0x5016e3a0 in throw_exception (ex=0x50815000) at 
> /usr/src/lib/libcxxrt/../../contrib/libcxxrt/exception.cc:751
> #3  0x1d50 in main () at exception_test.cpp:5

_Unwind_RaiseException never returns for source code that looks like:

> #include 
> 
> int main(void)
> {
> try { throw std::exception(); }
> catch (std::exception& e) {}
> return 0;
> }

where in /usr/lib/libc++.so.1 there is:

> 736   static void throw_exception(__cxa_exception *ex)
> 737   {
> . . .
> 751   _Unwind_Reason_Code err = 
> _Unwind_RaiseException(>unwindHeader);
> . . .
> 756   }

The unbounded loop in _Unwind_RaiseException is in the code:

> 85_Unwind_Reason_Code
> 86_Unwind_RaiseException(struct _Unwind_Exception *exc)
> 87{
> 88  struct _Unwind_Context this_context, cur_context;
> 89  _Unwind_Reason_Code code;
> 90
> 91  /* Set up this_context to describe the current stack frame.  */
> 92  uw_init_context (_context);
> 93  cur_context = this_context;
> 94
> 95  /* Phase 1: Search.  Unwind the stack, calling the personality routine
> 96 with the _UA_SEARCH_PHASE flag set.  Do not modify the stack yet.  
> */
> 97  while (1)
> 98{
> 99  _Unwind_FrameState fs;
> 100   
> 101 /* Set up fs to describe the FDE for the caller of cur_context.  
> The
> 102first time through the loop, that means __cxa_throw.  */
> 103 code = uw_frame_state_for (_context, );
> . . .
> 125 /* Update cur_context to describe the same frame as fs.  */
> 126 uw_update_context (_context, );
> 127   }
> . . .
> 140   }

The uw_update_context call is doing the following before returning:

> 1367/* Compute the return address now, since the return address column
> 1368   can change from frame to frame.  */
> 1369context->ra = __builtin_extract_return_addr
> 1370  (_Unwind_GetPtr (context, fs->retaddr_column));

with context->ra before and after the call both being 0x5016e3a0 . In fact it 
was 0x5016e3a0 for the prior uw_frame_state_for call as well and continues to 
be so each loop iteration once the problem starts.

As for the code around 0x5016e3a0:

>0x5016e398 :stw 
> r10,48(r9)
>0x5016e39c :bl  
> 0x50162ae0 <0017.plt_call._Unwind_RaiseException@@GCC_3.0>
>0x5016e3a0 :ld  
> r2,40(r1)
>0x5016e3a4 :addi
> r1,r1,128
>0x5016e3a8 :mr  
> r4,r31
>0x5016e3ac :ld  
> r0,16(r1)

 From /usr/local/bin/objdump for FreeBSD projects/clang380-import -r295902's 
/usr/lib/libc++.so.1 for the same code (to match up with the .eh_frame dwarf 
information):

> 00015398 <.__cxa_end_catch+0x4d8> stw r10,48(r9)
> 0001539c <.__cxa_end_catch+0x4dc> bl  9ae0 
> 
> 000153a0 <.__cxa_end_catch+0x4e0> ld  r2,40(r1)
> 000153a4 <.__cxa_end_catch+0x4e4> addir1,r1,128
> 000153a8 <.__cxa_end_catch+0x4e8> mr  r4,r31
> 000153ac <.__cxa_end_catch+0x4ec> ld  r0,16(r1)

The code block above from 153a0 up to 153a8 is being given 153a0 as its "return 
address" (context->ra) by uw_update_context via interpreting the dwarf 
.eh_frame information. So once in that range there it never leaves that range.

The relevant dwarfdump output spanning that area is:
(Note that 153a0 up to 153a8 is part of the range that includes the bl to 
_Unwind_RaiseException .)

> <0><0x00015310:0x000153dc><> aug data len 0x0>
> 0x00015310:  
> 0x00015318:
> 0x00015324:
> 0x00015368:
> 0x00015378:  
> 0x00015380:
> 0x000153a8:
> 0x000153b8:  
> 0x000153c0:
>  fde section offset 4312 0x10d8 cie offset for fde: 4316 0x10dc
>  0 DW_CFA_advance_loc 8  (2 * 

projects/clang380-import for TARGET_ARCH=powerpc64: /lib/libgcc_s.so.1 is incompatible with using the pair: /usr/lib/libc++.so.1 and /lib/libcxxrt.so.1 for C++ exception handling

2016-02-23 Thread Mark Millard
For TARGET_ARCH=powerpc64 it looks like FreeBSD's /lib/libgcc_s.so.1 is 
incompatible with using the pair: /usr/lib/libc++.so.1 and /lib/libcxxrt.so.1 .

Evidence details follow. (Now using projects/clang380-import -r295902 as a 
context.)

src.conf was set up to have things such that the buildworld/buildkernel that 
this is based on was via :

devel/powerpc64-gcc as the (self hosted) cross compiler
( /usr/local/bin/powerpc64-portbld-freebsd11.0-g++ )

and clang 3.8.0 as the "host" compiler.

Later below I list the ldd output for compiling the exception_test.cpp example 
under different compilers with different options that change what ldd shows and 
how .so's are found/bound. Some are implicitly using. . .

ELF ldconfig path: /lib /usr/lib /usr/lib/compat /usr/local/lib 
/usr/local/lib/compat/pkg /usr/local/lib/compat/pkg /usr/local/lib/gcc49 
/usr/local/lib/gcc6

and others are explicitly bound, such as by -Wl,-rpath= .

The only combinations that get the unbounded looping internal to exception 
handling are the ones that mix 3 things together:

/usr/lib/libc++.so.1
/lib/libcxxrt.so.1
/lib/libgcc_s.so.1

That is: exception_test.clang++380.powerpc64 and 
exception_test.powerpc64-gcc.powerpc64 get the unbounded looping and the others 
work fine.

Note that all 3 libraries were built by devel/powerpc64-gcc during buildworld, 
not by clang 3.8.0 . And exception_test.powerpc64-gcc.powerpc64 does not 
involve clang 3.8.0 based code at all.

Still libc++.so.1 and libcxxrt.so.1 are "foreign" relative to libgcc_s.so.1 and 
so there being some form of mismatch possible makes some sense.


That same /lib/libgcc_s.so.1 works fine with:

/usr/local/lib/gcc49/libstdc++.so.6
and
/usr/local/lib/gcc6/libstdc++.so.6

Of course a matched libstdc++/libgcc_s pair for a specific g++ compiler also 
works.

The combinations tested are . . .

# ldd *powerpc64
exception_test.clang++380.powerpc64:
libc++.so.1 => /usr/lib/libc++.so.1 (0x50054000)
libcxxrt.so.1 => /lib/libcxxrt.so.1 (0x5015a000)
libm.so.5 => /lib/libm.so.5 (0x50181000)
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x501be000)
libc.so.7 => /lib/libc.so.7 (0x501e4000)
exception_test.g++49-implicitgcc49.powerpc64:
libstdc++.so.6 => /usr/local/lib/gcc49/libstdc++.so.6 (0x50054000)
libm.so.5 => /lib/libm.so.5 (0x501ed000)
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x5022a000)
libc.so.7 => /lib/libc.so.7 (0x5025)
exception_test.g++49.powerpc64:
libstdc++.so.6 => /usr/local/lib/gcc49/libstdc++.so.6 (0x50054000)
libm.so.5 => /lib/libm.so.5 (0x501ed000)
libgcc_s.so.1 => /usr/local/lib/gcc49/libgcc_s.so.1 (0x5022a000)
libc.so.7 => /lib/libc.so.7 (0x50253000)
exception_test.g++6-implicitgcc49.powerpc64:
libstdc++.so.6 => /usr/local/lib/gcc49/libstdc++.so.6 (0x50054000)
libm.so.5 => /lib/libm.so.5 (0x501ed000)
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x5022a000)
libc.so.7 => /lib/libc.so.7 (0x5025)
exception_test.g++6.powerpc64:
libstdc++.so.6 => /usr/local/lib/gcc6/libstdc++.so.6 (0x50054000)
libm.so.5 => /lib/libm.so.5 (0x502a6000)
libgcc_s.so.1 => /usr/local/lib/gcc6/libgcc_s.so.1 (0x502e3000)
libc.so.7 => /lib/libc.so.7 (0x5030a000)
exception_test.powerpc64-gcc.powerpc64:
libc++.so.1 => /usr/lib/libc++.so.1 (0x50053000)
libcxxrt.so.1 => /lib/libcxxrt.so.1 (0x50159000)
libm.so.5 => /lib/libm.so.5 (0x5018)
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x501bd000)
libc.so.7 => /lib/libc.so.7 (0x501e3000)


NOTE: Why no g++5 test using its /usr/local/lib/gcc5/libstdc++.so.6?

Currently devel/powerpc64-gcc and lang/gcc5 are both at 5.3 and that makes them 
conflict on files if one tries to build both ports.

So I have just devel/powerpc64-gcc, the "officially produced" cross compiler 
port for targeting modernized powerpc64 builds.

===
Mark Millard
markmi at dsl-only.net

___
freebsd-toolchain@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/freebsd-toolchain
To unsubscribe, send any mail to "freebsd-toolchain-unsubscr...@freebsd.org"