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= --with-local-prefix= --with-headers=
--with-libs= --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=
--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
(/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
/armeb-linux/libstdc++-v3/include/armeb-linus/bits/gthr.h, which is
copied from /gcc/gthr.h).
In gthr.h, there is a list of conditional includes:
/* Check first for thread specific defines. */
#if _GLIBCXX__PTHREADS
#include
#elif _GLIBCXX__DCE_THREADS
#include
#elif _GLIBCXX__SOLARIS_THREADS
#include
/* 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
/* Fallback to single thread definitions. */
#else
#include
#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
(/armeb-linux/libstdc++-v3/src/atomicity.cc). This file contains a
couple of default atomic oparerations: __exchange_and_add and __atomic_add:
#include
#include
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
/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:
/gcc/xgcc -shared-libgcc -B/gcc/ -nostdinc++
-L/armeb-linux/libstdc++-v3/src
-L/armeb-linux/libstdc++-v3/src/.libs
-B/armeb-linux/armeb-linux/bin/ -B/armeb-linux/armeb-linux/lib/
-isystem /armeb-linux/armeb-linux/include -isystem /armeb-linux/armeb-linux/sys-include
-I/armeb-linux/libstdc++-v3/include/armeb-linux
-I/armeb-linux/libstdc++-v3/include -I/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