Patchwork [libitm] Link eh-1.exe with -shared-libgcc on Solaris (PR libitm/51822)

login
register
mail settings
Submitter Rainer Orth
Date Jan. 16, 2012, 5:07 p.m.
Message ID <yddvcob60eu.fsf@manam.CeBiTec.Uni-Bielefeld.DE>
Download mbox | patch
Permalink /patch/136320/
State New
Headers show

Comments

Rainer Orth - Jan. 16, 2012, 5:07 p.m.
As reported in PR libitm/51822, the libitm.c++/eh-1.C test FAILs on
Solaris with 

terminate called after throwing an instance of 'int'

I found that the failures are for two different reasons:

* Enabling ld.so.1 debugging (LD_DEBUG=bindings), it turned out that the
  64-bit failures on Solaris 10 and 11 happen since
  _Unwind_RaiseException from libc is used:

25243: 1: binding file=../../../gcc/amd64/libgcc_s.so.1 (0xfffffd7fc21e6910:0x16910) at plt[27]:full to file=/lib/64/libc.so.1 (0xfffffd7fff05a250:0x12a250): symbol '_Unwind_RaiseException'

  Unlike SPARC and the 32-bit libc, the 64-bit one provides an
  implementation of the unwinder, which seems to break this test.
  Linking the test with -shared-libgcc fixes it.

* The 32-bit failures on Solaris 8 to 10 have a different root cause:
  _Unwind_Find_FDE returns NULL for an address in _ZGTtL2f1v (f1()).  It
  turns out that there are two copies of the unwinder in eh-1.exe: one
  from libgcc_s.so.1, and another one from libgcc_eh.a.  eh-1.o has a
  reference to _Unwind_Resume (don't yet know why), which is resolved
  from libgcc_eh.a.  This doesn't happen on Solaris 11, which uses the
  dl_iterate_phdr based unwinder, thus no __register_frame_info_bases.

  Again, linking with shared-libgcc allows the testcase to succeed.

Bootstrapped without regressions on i386-pc-solaris2.11.

Ok for mainline?

	Rainer


2012-01-15  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>

	PR libitm/51822
	* testsuite/libitm.c++/eh-1.C: Add -shared-libgcc on *-*-solaris2*.
Richard Henderson - Jan. 23, 2012, 12:45 a.m.
On 01/17/2012 04:07 AM, Rainer Orth wrote:
> * The 32-bit failures on Solaris 8 to 10 have a different root cause:
>   _Unwind_Find_FDE returns NULL for an address in _ZGTtL2f1v (f1()).  It
>   turns out that there are two copies of the unwinder in eh-1.exe: one
>   from libgcc_s.so.1, and another one from libgcc_eh.a.  eh-1.o has a
>   reference to _Unwind_Resume (don't yet know why), which is resolved
>   from libgcc_eh.a.  This doesn't happen on Solaris 11, which uses the
>   dl_iterate_phdr based unwinder, thus no __register_frame_info_bases.

Er.. how did we get two copies?

I don't think this change is correct, as it seems just as likely
that we'd hit the same problem with real applications.  This just
seems like it's papering over the real problem.


r~
Rainer Orth - Jan. 24, 2012, 1:03 p.m.
Richard Henderson <rth@redhat.com> writes:

> On 01/17/2012 04:07 AM, Rainer Orth wrote:
>> * The 32-bit failures on Solaris 8 to 10 have a different root cause:
>>   _Unwind_Find_FDE returns NULL for an address in _ZGTtL2f1v (f1()).  It
>>   turns out that there are two copies of the unwinder in eh-1.exe: one
>>   from libgcc_s.so.1, and another one from libgcc_eh.a.  eh-1.o has a
>>   reference to _Unwind_Resume (don't yet know why), which is resolved
>>   from libgcc_eh.a.  This doesn't happen on Solaris 11, which uses the
>>   dl_iterate_phdr based unwinder, thus no __register_frame_info_bases.
>
> Er.. how did we get two copies?

The link line boils down to

ld -o eh-1.exe crt1.o crti.o crtbegin.o eh-1.o -litm -lstdc++ -lm -lgcc -lgcc_eh -lc -lgcc -lgcc_eh crtend.o crtn.o

The eh-1.o reference to _Unwind_Resume drags in one copy of the unwinder
from libgcc_eh.a, while libstdc++.so is linked against libgcc_s.so.1,
providing another copy.

> I don't think this change is correct, as it seems just as likely
> that we'd hit the same problem with real applications.  This just
> seems like it's papering over the real problem.

Quite possible.

	Rainer
Richard Henderson - Jan. 24, 2012, 6:47 p.m.
On 01/25/2012 12:03 AM, Rainer Orth wrote:
>> Er.. how did we get two copies?
> 
> The link line boils down to
> 
> ld -o eh-1.exe crt1.o crti.o crtbegin.o eh-1.o -litm -lstdc++ -lm -lgcc -lgcc_eh -lc -lgcc -lgcc_eh crtend.o crtn.o
> 
> The eh-1.o reference to _Unwind_Resume drags in one copy of the unwinder
> from libgcc_eh.a, while libstdc++.so is linked against libgcc_s.so.1,
> providing another copy.

So... are we linking with the gcc binary, not the g++ binary?
Because I thought -shared-libgcc is the default for C++.

If this goes too far down a rat-hole, your original patch is ok.


r~
Rainer Orth - Jan. 25, 2012, 9:57 a.m.
Richard Henderson <rth@redhat.com> writes:

>> The eh-1.o reference to _Unwind_Resume drags in one copy of the unwinder
>> from libgcc_eh.a, while libstdc++.so is linked against libgcc_s.so.1,
>> providing another copy.
>
> So... are we linking with the gcc binary, not the g++ binary?

Right.  This was just copied over from libgomp, like most of the libitm
build and test framework.

> Because I thought -shared-libgcc is the default for C++.

Indeed: manually replacing xgcc with g++ in the link line fixes the
test, and is certainly far better than a per-platform per-test
workaround.

I'll see what it takes to properly fix that.

> If this goes too far down a rat-hole, your original patch is ok.

Thanks.
	Rainer

Patch

# HG changeset patch
# Parent b41d70648bc4d3ba4c7930a694c0100973a1ed01
Link eh-1.exe with -shared-libgcc on Solaris (PR libitm/51822)

diff --git a/libitm/testsuite/libitm.c++/eh-1.C b/libitm/testsuite/libitm.c++/eh-1.C
--- a/libitm/testsuite/libitm.c++/eh-1.C
+++ b/libitm/testsuite/libitm.c++/eh-1.C
@@ -1,4 +1,5 @@ 
 // { dg-do run }
+// { dg-options "-shared-libgcc" { target *-*-solaris2* } }
 
 extern "C" void abort ();