GCC 3.4 and glibc/nptl: Cancellation broken
Jakub Jelinek
jakub@redhat.com
Thu Jan 22 17:00:00 GMT 2004
On Thu, Jan 22, 2004 at 04:23:37PM +0100, Andreas Jaeger wrote:
>
> On both i686 and amd64 (no other platforms tested) the current CVS
> glibc with nptl enabled does not pass the nptl testsuite when compiled
> with GCC 3.4 CVS. The failing tests include:
>
> tst-cancelx{4,5,10,11,12,14,15,16,17,18,20,21}
> tst-cleanupx{0,1,3,4}
>
> Note that the tests without the 'x' work. AFAIK the only difference
> between them is the usage of -fexceptions for the ones with the x.
>
> On AMD64 I get the following (i686 is equivalent) backtrace for
> nptl/tst-cleanupx0:
...
> The problem seems to be that the unwind functions are both in the
> executable image and in libgcc_s which is loaded by glibc (via
> dlopen).
>
> The actual problem then is that the called _Unwind_ForcedUnwind is
> From gcc_s and initializes its static dwarf_reg_size_table. But later
> the _Unwind_SetGR in the executable is called from the personality
> routine which looks at its own static dwarf_reg_size_table - and this
> one was never initialized and this leads to the abort.
>
> The unwind functions in the executable come from libgcc_eh.a and those
> From libgcc_s are dynamically loaded.
>
> Note this works with GCC 3.3.
>
> How is this supposed to work properly - and why does it work with 3.3
> but not with 3.4?
GCC 3.3 did not have the HPUX bloat in it.
One way to get around this quickly could be to:
- size = dwarf_reg_size_table[index];
ptr = context->reg[index];
+ if (sizeof (_Unwind_Ptr) == sizeof (_Unwind_Word))
+ return * (_Unwind_Word *) ptr;
+
+ size = dwarf_reg_size_table[index];
/* This will segfault if the register hasn't been saved. */
if (size == sizeof(_Unwind_Ptr))
return * (_Unwind_Ptr *) ptr;
if (size == sizeof(_Unwind_Word))
return * (_Unwind_Word *) ptr;
abort ();
in _Unwind_GetGR and similarly with _Unwind_SetGR.
Another temporary solution can be linking all NPTL -fexceptions C
programs with -shared-libgcc for the time being.
As soon as I implement (or anyone else beats me to do it)
http://sources.redhat.com/ml/binutils/2003-12/msg00211.html
GCC driver should link all non-static binaries with:
--start-only-if-used -lgcc_s --end-only-if-used
and things will work just fine.
Jakub
More information about the Libc-alpha
mailing list