When attempting to build an armeb-linux cross compiler on a RH Enterprise Linux
3.0 system, libstdc++ is not being built in a thread-safe manner.  Here is the
configure command line:

configure --cache-file=./config.cache --host=armeb-linux
--build=i686-pc-linux-gnu --enable-multilib --with-cross-host=i686-pc-linux-gnu
--prefix=<snip> --with-local-prefix=<snip> --with-headers=<snip>
--with-libs=<snip> --disable-nls --enable-threads=posix --enable-symvers=gnu
--enable-__cxa_atexit --enable-languages=c,c++ --enable-shared
--enable-long-long --with-cpu=arm9tdmi --enable-cxx-flags=-mcpu=arm9tdmi
--with-float=soft --with-gcc-version-trigger=<snip>
--program-transform-name=s,^,armeb-linux-,; 
--srcdir=../../../../gcc-3.4.3/libstdc++-v3 --with-target-subdir=armeb-linux


--enable-threads=posix is passed in, and looking at config.log, I see that it's
appearing to be honored correctly, since "glibcxx_thread_h" is being set to
"gthr-posix.h".  When I go into the build target directory
(<prefix>/armeb-linux/libstdc++-v3/include/bits), I can see that gthr-default.h
is indeed copied from gthr-posix.h  Thus, it would appeard that gthr-default.h
is correct.  With that said, the real problem appears to be in the use of
gthr.h (which originates from
<prefix>/armeb-linux/libstdc++-v3/include/armeb-linus/bits/gthr.h, which is
copied from <build source>/gcc/gthr.h).

In gthr.h, there is a list of conditional includes:
/* Check first for thread specific defines.  */
#if _GLIBCXX__PTHREADS
#include <bits/gthr-posix.h>
#elif _GLIBCXX__DCE_THREADS
#include <bits/gthr-dce.h>
#elif _GLIBCXX__SOLARIS_THREADS
#include <bits/gthr-solaris.h>

/* Include GTHREAD_FILE if one is defined.  */
#elif defined(_GLIBCXX_HAVE_GTHR_DEFAULT)
#if __GXX_WEAK__
#ifndef _GLIBCXX_GTHREAD_USE_WEAK
#define _GLIBCXX_GTHREAD_USE_WEAK 1
#endif
#endif
#include <bits/gthr-default.h>

/* Fallback to single thread definitions.  */
#else
#include <bits/gthr-single.h>
#endif

I would expect, on my system, to either have -D_GLIBCXX__PTHREADS or
-D_GLIBCXX_HAVE_GTHR_DEFAULT.  I see neither.  I do see
_GLIBCXX_HAVE_GTHR_DEFAULT defined in c++config.h, though.  Unfortunately,
gthr.h does not include c++config.h, so it does now see that there is a
gthr-default.h header available to include.  The result is that files that
include gthr.h are not guaranteed to pull in the proper thread support
routines.  I first ran into this problem with the file atomicity.cc
(<prefix>/armeb-linux/libstdc++-v3/src/atomicity.cc).  This file contains a
couple of default atomic oparerations: __exchange_and_add and __atomic_add:

#include <bits/atomicity.h>
#include <bits/concurrence.h>

namespace __gnu_internal
{
  __glibcxx_mutex_define_initialized(atomic_mutex);
} // namespace __gnu_internal

namespace __gnu_cxx
{
  _Atomic_word
  __attribute__ ((__unused__))
  __exchange_and_add(volatile _Atomic_word* __mem, int __val)
  {
    __glibcxx_mutex_lock(__gnu_internal::atomic_mutex);
    _Atomic_word __result;
    __result = *__mem;
    *__mem += __val;
    __glibcxx_mutex_unlock(__gnu_internal::atomic_mutex);
    return __result;
  }

  void
  __attribute__ ((__unused__))
  __atomic_add(volatile _Atomic_word* __mem, int __val)
  { __exchange_and_add(__mem, __val); }
} // namespace __gnu_cxx


The exchange and add routine is absurdly simple in that it creates a critical
section around the add to ensure that it's an atomic operation.  In theory, the
include of bits/concurrence.h should pull in the definitions of
__glibcxx_mutex_lock and __glibcxx_mutex_unlock.  This is unforutanately not
the case.  The file
<prefix>/armeb-linux/libstdc++-v3/include/bits/concurrence.h includes
"bits/gthr.h".  But... c++config.h is not included anywhere.  Also, the compile
line for atomicity.cc does not have any of the necessary gthr.h macros defined,
either:

<prefix>/gcc/xgcc -shared-libgcc -B<prefix>/gcc/ -nostdinc++
-L<prefix>/armeb-linux/libstdc++-v3/src
-L<prefix>/armeb-linux/libstdc++-v3/src/.libs
-B<prefix>/armeb-linux/armeb-linux/bin/ -B<prefix>/armeb-linux/armeb-linux/lib/
-isystem <install dir>/armeb-linux/armeb-linux/include -isystem <install
dir>/armeb-linux/armeb-linux/sys-include
-I<prefix>/armeb-linux/libstdc++-v3/include/armeb-linux
-I<prefix>/armeb-linux/libstdc++-v3/include -I<source
dir>/libstdc++-v3/libsupc++ -O2 -g -O2 -g -O2 -D_GNU_SOURCE
-fno-implicit-templates -Wall -W -Wwrite-strings -Wcast-qual
-fdiagnostics-show-location=once -ffunction-sections -fdata-sections
-mcpu=arm9tdmi -c atomicity.cc -o atomicity.o

The result of this is that atomicity.o is built without any thread safety. 
This means that operations such as the reference count inrement and decrement
in std::string are not safe.

Thanks
-Seth Moore


-- 
           Summary: Macro definitions needed by gcc/gthr.h are missing from
                    libstdc++ build
           Product: gcc
           Version: 3.4.3
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: libstdc++
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: sethmoore at gmail dot com
 GCC build triplet: i686-pc-linux-gnu
  GCC host triplet: armeb-unknown-linux-gnu
GCC target triplet: armeb-unknown-linux-gnu


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=28961

Reply via email to