This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
libgomp crash fix
- From: Bruno Haible <bruno at clisp dot org>
- To: Richard Henderson <rth at redhat dot com>, Tom Tromey <tromey at redhat dot com>
- Cc: gcc at gcc dot gnu dot org
- Date: Wed, 8 Nov 2006 14:33:08 +0100
- Subject: libgomp crash fix
Hi,
Bug #28468 (http://gcc.gnu.org/bugzilla/show_bug.cgi?id=28468)
causes a crash of nearly every valid program that parallelizes a loop
through OMP when OMP_NUM_THREADS > 1.
The affected systems are probably all Linux/x86 systems on which a glibc
with LinuxThreads and without TLS is installed, and on which binutils
with __thread support were installed afterwards.
The typical gdb stack trace is like this:
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 16386 (LWP 4985)]
gomp_iter_dynamic_next (pstart=0xbf7ffa94, pend=0xbf7ffa98) at ../../../gcc-4.2-20061031/libgomp/iter.c:189
189 start = ws->next;
(gdb) where
#0 gomp_iter_dynamic_next (pstart=0xbf7ffa94, pend=0xbf7ffa98) at ../../../gcc-4.2-20061031/libgomp/iter.c:189
#1 0x4001ca78 in gomp_loop_dynamic_next (istart=0xbf7ffa94, iend=0xbf7ffa98) at ../../../gcc-4.2-20061031/libgomp/loop.c:248
#2 0x080486ed in main.omp_fn.0 ()
#3 0x4001de5d in gomp_thread_start (xdata=0xbfffe580) at ../../../gcc-4.2-20061031/libgomp/team.c:108
#4 0x4003bfe6 in pthread_start_thread (arg=0xbf7ffbe0) at manager.c:310
#5 0x4003c07f in pthread_start_thread_event (arg=0xbf7ffbe0) at manager.c:334
#6 0x4014e0aa in clone () from /lib/libc.so.6
What happens is that gomp_thread () returns a pointer to a memory area that
consistents entirely of zeroes.
The gomp_thread() definition in libgomp.h:227 is used, making an access to
%gs:0. This is wrong, because the libc in use does not support this %gs stuff.
So, the reason is that HAVE_TLS was defined although only binutils and gcc,
but not glibc, support TLS.
After I changed the GCC_CHECK_TLS macro to also test for libc support of
__thread, rebuilt libcomp/configure, ran "config.status --recheck" and
rebuilt and reinstalled libgomp, the crash went away.
Here is the fix. It tests whether __thread actually works, not only whether
it is syntactically valid for the compiler. I have already submitted
copyright assignment papers for GCC.
2006-11-07 Bruno Haible <bruno@clisp.org>
* config/tls.m4 (GCC_CHECK_TLS): Also check whether the libc supports
TLS via __thread.
*** config/tls.m4 2006-09-19 03:48:06.000000000 +0200
--- config/tls.m4.new 2006-11-08 01:47:33.000000000 +0100
***************
*** 11,17 ****
LDFLAGS="-static $LDFLAGS"
AC_RUN_IFELSE([__thread int a; int b; int main() { return a = b; }],
[have_tls=yes], [have_tls=no], [])
! LDFLAGS="$save_LDFLAGS"],
[have_tls=no],
[AC_COMPILE_IFELSE([__thread int foo;], [have_tls=yes], [have_tls=no])]
)])
--- 11,53 ----
LDFLAGS="-static $LDFLAGS"
AC_RUN_IFELSE([__thread int a; int b; int main() { return a = b; }],
[have_tls=yes], [have_tls=no], [])
! LDFLAGS="$save_LDFLAGS"
! if test $have_tls = yes; then
! dnl So far, the binutils and the compiler support TLS.
! dnl Also check whether the libc supports TLS, i.e. whether a variable
! dnl with __thread linkage has a different address in different threads.
! save_LDFLAGS="$LDFLAGS"
! LDFLAGS="-lpthread $LDFLAGS"
! AC_RUN_IFELSE([
! #include <pthread.h>
!
! __thread int a;
! int *mainthread_a;
! int *subthread_a;
!
! void *subthread_func(void *arg)
! {
! subthread_a = &a;
! return 0;
! }
!
! int main()
! {
! pthread_t subthread;
! void *subthread_retval;
!
! mainthread_a = &a;
!
! if (pthread_create (&subthread, NULL, subthread_func, 0) != 0)
! return 2;
! if (pthread_join (subthread, &subthread_retval) != 0)
! return 3;
!
! return (mainthread_a == subthread_a);
! }],
! [have_tls=yes], [have_tls=no], [])
! LDFLAGS="$save_LDFLAGS"
! fi],
[have_tls=no],
[AC_COMPILE_IFELSE([__thread int foo;], [have_tls=yes], [have_tls=no])]
)])