Red Hat Bugzilla – Bug 128912
pthread_exit linked on RHEL2.1 ia64 crashes on RHEL3
Last modified: 2007-11-30 17:07:03 EST
1) We compiled the program under RHEL 2.1:
Red Hat Linux Advanced Server release 2.1AS (Derry)
Linux rhia202 2.4.18-e.12smp #1 SMP Thu Oct 17 15:13:01 EDT 2002 ia64
2) Program compiled using:
gcc -pthread t.c -o t -g
3) Program executed on RHEL 3.0
Red Hat Enterprise Linux AS release 3 (Taroon)
Linux inteleverest3 2.4.21-4.EL #1 SMP Fri Oct 3 17:29:39 EDT 2003
ia64 ia64 ia64 GNU/Linux
Program terminated with signal 11, Segmentation fault.
#0 0x2000000000819a40 in _Unwind_GetBSP () from /lib/libgcc_s.so.1
#1 0x2000000000819de0 in _Unwind_GetBSP () from /lib/libgcc_s.so.1
Previous frame identical to this frame (corrupt stack?)
Here's the program:
void *thread__func(void *dummy)
pthread_create(&thread, NULL, thread__func, (void *)&i);
Replacing pthread_exit(0) with return 0, the program does not crash.
Running the program on AS2.1, or on 3EL with Linuxthreads, it doesn't
crash. Only NPTL crashes, during stack unwinding.
On x86, the program works.
Created attachment 102334 [details]
Don't use _Unwind_ForcedUnwind if __libc_csu_init() is not defined
Although we could fix the problem in the AS2.1 crt1.o, adding unwind info to
its crt1.o, this wouldn't get programs built with the previous crt1.o to work.
For those, we'd need some work around in the RHEL3 libc. One symbol defined in
the new crt1.o, but not in older ones, is __libc_csu_init(). Testing for its
presence would be a relatively easy work around for the problem. However, if
the user chooses to hide this symbol in the main executable, it won't work.
Unfortunately, we can't just add some code to RHEL 3's crt1.o to set a flag in
pthread.so because then older RHEL3 programs would not use _Forced_Unwind.
However, we could use an inclusive combination of these two mechanisms: change
crt1.o to call a function optionally defined in libpthread to get this flag
set, and tweak pthread_init to set this same flag if __libc_csu_init is
defined. Should I implement this alternate, more complex patch, or is the one
above enough? Or should we come up with yet another approach?
Actually, this seems to be GCC 2.9x bug.
pthread_exit is __attribute__((noreturn)), and GCC 2.96-RH puts the
br.call.sptk.many b0 = pthread_exit#
instruction as the last instruction in the routine.
This breaks the unwinder, as call insn must not be the last one:
Current ia64.c has in ia64_reorg:
/* A call must not be the last instruction in a function, so that the
return address is still within the function, so that unwinding works
properly. Note that IA-64 differs from dwarf2 on this point. */
and inserts a break.f 0 instruction after the call if it is indeed the
last instruction in the routine.
Guess we need to backport it.
Guess the patch in question is:
2001-05-11 Richard Henderson <firstname.lastname@example.org>
* config/ia64/ia64.c (group_barrier_needed_p): Don't allow
calls and jumps to be bundled together.
(ia64_reorg): Emit a break after a noreturn call that ends
* config/ia64/ia64.md (break_f): New.
Should be fixed in gcc-2.96-129.7.2 in dist-2.1AS-errata-candidate.
I have uploaded them to
so that SyBase/MSDW can check it out.
An errata has been issued which should help the problem
described in this bug report. This report is therefore being
closed with a resolution of ERRATA. For more information
on the solution and/or where to find the updated files,
please follow the link below. You may reopen this bug report
if the solution does not work for you.