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